]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add Socket Libraries.
authordarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 30 Jul 2011 00:30:44 +0000 (00:30 +0000)
committerdarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 30 Jul 2011 00:30:44 +0000 (00:30 +0000)
Add Posix functions for porting compatibility.
Fix compliance issues with ISO/IEC 9899:199409
New Functions:
  setenv(), fparseln(), GetFileNameFromPath(), rename(),
  realpath(), setprogname(), getprogname(), strlcat(), strlcpy(),
  strsep(), setitimer(), getitimer(), timegm(), getopt(), basename(),
  mkstemp(), ffs(), vsnprintf(), snprintf(), getpass(), usleep(), select(),
  writev(), strcasecmp(), getcwd(), chdir(), tcgetpgrp(), getpgrp(), gettimeofday(),
  bcopy(),

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12061 6f19259b-4bc3-4df7-8a09-765794883524

199 files changed:
StdLib/BsdSocketLib/BsdSocketLib.inf [new file with mode: 0644]
StdLib/BsdSocketLib/SocketInternals.h [new file with mode: 0644]
StdLib/BsdSocketLib/Socklib_internals.h [new file with mode: 0644]
StdLib/BsdSocketLib/accept.c [new file with mode: 0644]
StdLib/BsdSocketLib/base64.c [new file with mode: 0644]
StdLib/BsdSocketLib/bind.c [new file with mode: 0644]
StdLib/BsdSocketLib/close.c [new file with mode: 0644]
StdLib/BsdSocketLib/connect.c [new file with mode: 0644]
StdLib/BsdSocketLib/errno.c [new file with mode: 0644]
StdLib/BsdSocketLib/gethostbydns.c [new file with mode: 0644]
StdLib/BsdSocketLib/gethostbyht.c [new file with mode: 0644]
StdLib/BsdSocketLib/gethostbynis.c [new file with mode: 0644]
StdLib/BsdSocketLib/gethostnamadr.c [new file with mode: 0644]
StdLib/BsdSocketLib/gethostname.c [new file with mode: 0644]
StdLib/BsdSocketLib/getnetbydns.c [new file with mode: 0644]
StdLib/BsdSocketLib/getnetbyht.c [new file with mode: 0644]
StdLib/BsdSocketLib/getnetbynis.c [new file with mode: 0644]
StdLib/BsdSocketLib/getnetnamadr.c [new file with mode: 0644]
StdLib/BsdSocketLib/getpeername.c [new file with mode: 0644]
StdLib/BsdSocketLib/getproto.c [new file with mode: 0644]
StdLib/BsdSocketLib/getprotoent.c [new file with mode: 0644]
StdLib/BsdSocketLib/getprotoname.c [new file with mode: 0644]
StdLib/BsdSocketLib/getservbyname.c [new file with mode: 0644]
StdLib/BsdSocketLib/getservbyport.c [new file with mode: 0644]
StdLib/BsdSocketLib/getservent.c [new file with mode: 0644]
StdLib/BsdSocketLib/getsockname.c [new file with mode: 0644]
StdLib/BsdSocketLib/getsockopt.c [new file with mode: 0644]
StdLib/BsdSocketLib/herror.c [new file with mode: 0644]
StdLib/BsdSocketLib/inet_net_ntop.c [new file with mode: 0644]
StdLib/BsdSocketLib/inet_net_pton.c [new file with mode: 0644]
StdLib/BsdSocketLib/inet_neta.c [new file with mode: 0644]
StdLib/BsdSocketLib/inet_pton.c [new file with mode: 0644]
StdLib/BsdSocketLib/listen.c [new file with mode: 0644]
StdLib/BsdSocketLib/map_v4v6.c [new file with mode: 0644]
StdLib/BsdSocketLib/ns_addr.c [new file with mode: 0644]
StdLib/BsdSocketLib/ns_name.c [new file with mode: 0644]
StdLib/BsdSocketLib/ns_netint.c [new file with mode: 0644]
StdLib/BsdSocketLib/ns_ntoa.c [new file with mode: 0644]
StdLib/BsdSocketLib/ns_parse.c [new file with mode: 0644]
StdLib/BsdSocketLib/ns_print.c [new file with mode: 0644]
StdLib/BsdSocketLib/ns_ttl.c [new file with mode: 0644]
StdLib/BsdSocketLib/nsap_addr.c [new file with mode: 0644]
StdLib/BsdSocketLib/poll.c [new file with mode: 0644]
StdLib/BsdSocketLib/read.c [new file with mode: 0644]
StdLib/BsdSocketLib/recv.c [new file with mode: 0644]
StdLib/BsdSocketLib/recvfrom.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_comp.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_config.h [new file with mode: 0644]
StdLib/BsdSocketLib/res_data.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_debug.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_init.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_mkquery.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_mkupdate.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_query.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_send.c [new file with mode: 0644]
StdLib/BsdSocketLib/res_update.c [new file with mode: 0644]
StdLib/BsdSocketLib/send.c [new file with mode: 0644]
StdLib/BsdSocketLib/sendto.c [new file with mode: 0644]
StdLib/BsdSocketLib/sethostname.c [new file with mode: 0644]
StdLib/BsdSocketLib/setsockopt.c [new file with mode: 0644]
StdLib/BsdSocketLib/shutdown.c [new file with mode: 0644]
StdLib/BsdSocketLib/socket.c [new file with mode: 0644]
StdLib/BsdSocketLib/write.c [new file with mode: 0644]
StdLib/Efi/etc/host.conf [new file with mode: 0644]
StdLib/Efi/etc/hosts [new file with mode: 0644]
StdLib/Efi/etc/networks [new file with mode: 0644]
StdLib/Efi/etc/protocols [new file with mode: 0644]
StdLib/Efi/etc/resolv.conf [new file with mode: 0644]
StdLib/Efi/etc/services [new file with mode: 0644]
StdLib/EfiSocketLib/EfiSocketLib.inf [new file with mode: 0644]
StdLib/EfiSocketLib/Init.c [new file with mode: 0644]
StdLib/EfiSocketLib/Service.c [new file with mode: 0644]
StdLib/EfiSocketLib/Socket.c [new file with mode: 0644]
StdLib/EfiSocketLib/Socket.h [new file with mode: 0644]
StdLib/EfiSocketLib/Tcp4.c [new file with mode: 0644]
StdLib/EfiSocketLib/Udp4.c [new file with mode: 0644]
StdLib/EfiSocketLib/UseEfiSocketLib.c [new file with mode: 0644]
StdLib/Include/Efi/EfiSocketLib.h [new file with mode: 0644]
StdLib/Include/Ia32/machine/limits.h
StdLib/Include/Protocol/EfiSocket.h [new file with mode: 0644]
StdLib/Include/X64/machine/limits.h
StdLib/Include/arpa/ftp.h [new file with mode: 0644]
StdLib/Include/arpa/nameser.h
StdLib/Include/arpa/telnet.h [new file with mode: 0644]
StdLib/Include/err.h [new file with mode: 0644]
StdLib/Include/errno.h
StdLib/Include/glob.h [new file with mode: 0644]
StdLib/Include/libgen.h [new file with mode: 0644]
StdLib/Include/net/if.h [new file with mode: 0644]
StdLib/Include/net/if_dl.h [new file with mode: 0644]
StdLib/Include/net/radix.h [new file with mode: 0644]
StdLib/Include/net/route.h [new file with mode: 0644]
StdLib/Include/netatalk/at.h [new file with mode: 0644]
StdLib/Include/netdb.h
StdLib/Include/netinet/in_systm.h [new file with mode: 0644]
StdLib/Include/netinet/ip.h [new file with mode: 0644]
StdLib/Include/netns/ns.h [new file with mode: 0644]
StdLib/Include/paths.h
StdLib/Include/pwd.h [new file with mode: 0644]
StdLib/Include/resolv.h [new file with mode: 0644]
StdLib/Include/signal.h
StdLib/Include/stdarg.h
StdLib/Include/stdio.h
StdLib/Include/stdlib.h
StdLib/Include/string.h
StdLib/Include/stringlist.h [new file with mode: 0644]
StdLib/Include/sys/EfiCdefs.h
StdLib/Include/sys/EfiSysCall.h
StdLib/Include/sys/_posix.h [new file with mode: 0644]
StdLib/Include/sys/cdefs_aout.h
StdLib/Include/sys/file.h [new file with mode: 0644]
StdLib/Include/sys/select.h
StdLib/Include/sys/signal.h
StdLib/Include/sys/sockio.h [new file with mode: 0644]
StdLib/Include/sys/stat.h
StdLib/Include/sys/sysctl.h [new file with mode: 0644]
StdLib/Include/sys/syslimits.h
StdLib/Include/sys/time.h
StdLib/Include/sys/unistd.h
StdLib/Include/sys/wait.h [new file with mode: 0644]
StdLib/Include/sysexits.h [new file with mode: 0644]
StdLib/Include/time.h
StdLib/Include/unistd.h
StdLib/Include/x86/limits.h
StdLib/LibC/Locale/Locale.inf
StdLib/LibC/Locale/_wcstoul.h
StdLib/LibC/Locale/multibyte_sb.c
StdLib/LibC/Main/Main.c
StdLib/LibC/Main/assert.c
StdLib/LibC/Main/x86flt_rounds.c
StdLib/LibC/NetUtil/NetUtil.inf
StdLib/LibC/StdLib/Environs.c
StdLib/LibC/StdLib/NumericInt.c
StdLib/LibC/StdLib/StdLib.inf
StdLib/LibC/StdLib/realpath.c [new file with mode: 0644]
StdLib/LibC/StdLib/setprogname.c [new file with mode: 0644]
StdLib/LibC/StdLib/strtoumax.c
StdLib/LibC/Stdio/Stdio.inf
StdLib/LibC/Stdio/freopen.c
StdLib/LibC/Stdio/fseeko.c
StdLib/LibC/Stdio/gettemp.c
StdLib/LibC/Stdio/local.h
StdLib/LibC/Stdio/mkstemp.c
StdLib/LibC/Stdio/setbuffer.c
StdLib/LibC/Stdio/vfwprintf.c
StdLib/LibC/Stdio/vfwscanf.c
StdLib/LibC/Stdio/vprintf.c
StdLib/LibC/Stdio/vsnprintf.c
StdLib/LibC/Stdio/vsnprintf_ss.c
StdLib/LibC/Stdio/vsprintf.c
StdLib/LibC/String/Comparison.c
StdLib/LibC/String/String.inf
StdLib/LibC/String/strlcat.c [new file with mode: 0644]
StdLib/LibC/String/strlcpy.c [new file with mode: 0644]
StdLib/LibC/String/strncasecmp.c
StdLib/LibC/String/strsep.c [new file with mode: 0644]
StdLib/LibC/Time/Time.c
StdLib/LibC/Time/Time.inf
StdLib/LibC/Time/TimeEfi.c
StdLib/LibC/Time/TimeVals.h
StdLib/LibC/Time/ZoneProc.c
StdLib/LibC/Time/gettimeofday.c
StdLib/LibC/Time/itimer.c [new file with mode: 0644]
StdLib/LibC/Time/strftime.c
StdLib/LibC/Time/timegm.c [new file with mode: 0644]
StdLib/LibC/Uefi/Devices/Console/daConsole.c
StdLib/LibC/Uefi/Devices/UefiShell/daShell.c
StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c
StdLib/LibC/Uefi/Devices/Utility/Path.c
StdLib/LibC/Uefi/Devices/daConsole.inf
StdLib/LibC/Uefi/Devices/daShell.inf
StdLib/LibC/Uefi/Devices/daUtility.inf
StdLib/LibC/Uefi/GetPass.c [new file with mode: 0644]
StdLib/LibC/Uefi/StubFunctions.c [new file with mode: 0644]
StdLib/LibC/Uefi/SysCalls.c
StdLib/LibC/Uefi/Uefi.inf
StdLib/LibC/Uefi/compat.c [new file with mode: 0644]
StdLib/LibC/Uefi/select.c [new file with mode: 0644]
StdLib/LibC/Uefi/writev.c [new file with mode: 0644]
StdLib/PosixLib/Err/LibErr.inf [new file with mode: 0644]
StdLib/PosixLib/Err/warn_err.c [new file with mode: 0644]
StdLib/PosixLib/Gen/LibGen.inf [new file with mode: 0644]
StdLib/PosixLib/Gen/dirname.c [new file with mode: 0644]
StdLib/PosixLib/Glob/DirFunctions.c [new file with mode: 0644]
StdLib/PosixLib/Glob/LibGlob.inf [new file with mode: 0644]
StdLib/PosixLib/Glob/glob.c [new file with mode: 0644]
StdLib/PosixLib/Glob/internal.h [new file with mode: 0644]
StdLib/PosixLib/Stringlist/LibStringlist.inf [new file with mode: 0644]
StdLib/PosixLib/Stringlist/stringlist.c [new file with mode: 0644]
StdLib/SocketDxe/ComponentName.c [new file with mode: 0644]
StdLib/SocketDxe/DriverBinding.c [new file with mode: 0644]
StdLib/SocketDxe/EntryUnload.c [new file with mode: 0644]
StdLib/SocketDxe/Socket.h [new file with mode: 0644]
StdLib/SocketDxe/SocketDxe.inf [new file with mode: 0644]
StdLib/StdLib.dec
StdLib/StdLib.dsc
StdLib/StdLib.inc [new file with mode: 0644]
StdLib/UseSocketDxe/UseSocketDxe.c [new file with mode: 0644]
StdLib/UseSocketDxe/UseSocketDxe.inf [new file with mode: 0644]

diff --git a/StdLib/BsdSocketLib/BsdSocketLib.inf b/StdLib/BsdSocketLib/BsdSocketLib.inf
new file mode 100644 (file)
index 0000000..3337acb
--- /dev/null
@@ -0,0 +1,115 @@
+#/** @file\r
+# Component description file for the socket library.\r
+#\r
+# This module implements the socket library.\r
+# Copyright (c) 2011, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BsdSocketLib\r
+  FILE_GUID                      = E7A79769-DD6E-48f7-B90B-D4C510AC1741\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = BsdSocketLib\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  accept.c\r
+  base64.c\r
+  bind.c\r
+  close.c\r
+  connect.c\r
+  gethostbydns.c\r
+  gethostbyht.c\r
+  gethostbynis.c\r
+  gethostname.c\r
+  gethostnamadr.c\r
+  gethostbynis.c\r
+  getnetbydns.c\r
+  getnetbynis.c\r
+  getnetbyht.c\r
+  getnetnamadr.c\r
+  getpeername.c\r
+  getprotoent.c\r
+  getprotoname.c\r
+  getproto.c\r
+  getservbyname.c\r
+  getservbyport.c\r
+  getservent.c\r
+  getsockname.c\r
+  getsockopt.c\r
+  herror.c\r
+#  inet_addr.c\r
+#  inet_lnaof.c\r
+#  inet_makeaddr.c\r
+  inet_net_ntop.c\r
+  inet_net_pton.c\r
+  inet_neta.c\r
+#  inet_netof.c\r
+#  inet_network.c\r
+#  inet_ntoa.c\r
+#  inet_ntop.c\r
+  inet_pton.c\r
+  listen.c\r
+  map_v4v6.c\r
+  ns_addr.c\r
+  ns_name.c\r
+  ns_netint.c\r
+  ns_ntoa.c\r
+  ns_parse.c\r
+  ns_print.c\r
+  ns_ttl.c\r
+  nsap_addr.c\r
+  poll.c\r
+  read.c\r
+  recv.c\r
+  recvfrom.c\r
+  res_comp.c\r
+  res_config.h\r
+  res_data.c\r
+  res_debug.c\r
+  res_init.c\r
+  res_mkquery.c\r
+  res_mkupdate.c\r
+  res_query.c\r
+  res_send.c\r
+  res_update.c\r
+  send.c\r
+  sendto.c\r
+  sethostname.c\r
+  setsockopt.c\r
+  shutdown.c\r
+  socket.c\r
+  SocketInternals.h\r
+  write.c\r
+\r
+[Packages]\r
+  StdLib/StdLib.dec\r
+  StdLibPrivateInternalFiles/DoNotUse.dec\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+#  SocketPkg/SocketPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  DevUtility\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+\r
+[Protocols]\r
+  gEfiSocketServiceBindingProtocolGuid\r
+  gEfiSocketProtocolGuid\r
diff --git a/StdLib/BsdSocketLib/SocketInternals.h b/StdLib/BsdSocketLib/SocketInternals.h
new file mode 100644 (file)
index 0000000..57eed94
--- /dev/null
@@ -0,0 +1,190 @@
+/** @file\r
+  Definitions for the socket library.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _SOCKET_INTERNALS_H_\r
+#define _SOCKET_INTERNALS_H_\r
+\r
+#include <Uefi.h>\r
+\r
+//----------------------------------------------------------------------\r
+//\r
+//  The following private files are required to support file descriptors\r
+//\r
+\r
+#include <kfile.h>\r
+#include <MainData.h>\r
+\r
+#include <efi/SysEfi.h>\r
+\r
+//\r
+//  End of private files\r
+//\r
+//----------------------------------------------------------------------\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <Protocol/EfiSocket.h>\r
+#include <Protocol/ServiceBinding.h>\r
+\r
+#include <sys/errno.h>\r
+#include <sys/poll.h>\r
+#include <sys/EfiSysCall.h>\r
+#include <sys/socket.h>\r
+\r
+//------------------------------------------------------------------------------\r
+//  Support Routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Translate from the socket file descriptor to the socket protocol.\r
+\r
+  @param [in] s             Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] ppDescriptor  Address to receive the descriptor structure\r
+                            address for the file\r
+  @param [in] pErrno        Address of the errno variable\r
+\r
+  @returns  A pointer to the socket protocol structure or NULL if\r
+            an invalid file descriptor was passed in.\r
+\r
+ **/\r
+EFI_SOCKET_PROTOCOL *\r
+BslFdToSocketProtocol (\r
+  int s,\r
+  struct __filedes ** ppDescriptor,\r
+  int * pErrno\r
+  );\r
+\r
+/**\r
+  Close the socket\r
+\r
+  @param [in] pDescriptor Descriptor address for the file\r
+\r
+  @returns  This routine returns 0 upon success and -1 upon failure.\r
+            In the case of failure, errno contains more information.\r
+\r
+**/\r
+INT32\r
+BslSocketClose (\r
+  struct __filedes * pDescriptor\r
+  );\r
+\r
+/**\r
+  Worker routine to close the socket.\r
+\r
+  @param [in] pSocketProtocol   Socket protocol structure address\r
+\r
+  @param [in] pErrno            Address of the errno variable\r
+\r
+  @retval EFI_SUCCESS   Successfully closed the socket\r
+\r
+**/\r
+EFI_STATUS\r
+BslSocketCloseWork (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Poll the socket for activity\r
+\r
+  @param [in] pDescriptor Descriptor address for the file\r
+\r
+  @param [in] Events      Mask of events to detect\r
+\r
+  @returns    Detected events for the socket\r
+\r
+ **/\r
+short\r
+BslSocketPoll (\r
+  IN struct __filedes * pDescriptor,\r
+  IN short Events\r
+  );\r
+\r
+/**\r
+  Build a file descriptor for a socket.\r
+\r
+  @param [in] pSocketProtocol   Socket protocol structure address\r
+  \r
+  @param [in] pErrno            Address of the errno variable\r
+\r
+  @returns The file descriptor for the socket or -1 if an error occurs.\r
+\r
+ **/\r
+int\r
+BslSocketProtocolToFd (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Read support routine for sockets\r
+\r
+  @param [in] pDescriptor   Descriptor address for the file\r
+  @param [in] pOffset       File offset\r
+  @param [in] LengthInBytes Number of bytes to read\r
+  @param [in] pBuffer       Address of the buffer to receive the data\r
+\r
+  @returns  The number of bytes read or -1 if an error occurs.\r
+\r
+**/\r
+ssize_t\r
+BslSocketRead (\r
+  struct __filedes *pDescriptor,\r
+  off_t * pOffset,\r
+  size_t LengthInBytes,\r
+  void * pBuffer\r
+  );\r
+\r
+/**\r
+  Write support routine for sockets\r
+\r
+  @param [in] pDescriptor   Descriptor address for the file\r
+  @param [in] pOffset       File offset\r
+  @param [in] LengthInBytes Number of bytes to write\r
+  @param [in] pBuffer       Address of the data\r
+\r
+  @returns  The number of bytes written or -1 if an error occurs.\r
+\r
+**/\r
+ssize_t\r
+BslSocketWrite (\r
+  struct __filedes *pDescriptor,\r
+  off_t * pOffset,\r
+  size_t LengthInBytes,\r
+  const void * pBuffer\r
+  );\r
+\r
+/**\r
+  Validate the socket's file descriptor\r
+\r
+  @param [in] pDescriptor Descriptor for the file\r
+\r
+  @param [in] pErrno      Address of the errno variable\r
+\r
+  @returns  A pointer to the socket protocol structure or NULL if\r
+            an invalid file descriptor was passed in.\r
+\r
+ **/\r
+EFI_SOCKET_PROTOCOL *\r
+BslValidateSocketFd (\r
+  struct __filedes * pDescriptor,\r
+  int * pErrno\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+#endif  //  _SOCKET_INTERNALS_H_\r
diff --git a/StdLib/BsdSocketLib/Socklib_internals.h b/StdLib/BsdSocketLib/Socklib_internals.h
new file mode 100644 (file)
index 0000000..802aaeb
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+  Definitions for the socket library functions that are used internally.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _SOCKLIB_INTERNALS_H_\r
+#define _SOCKLIB_INTERNALS_H_\r
+\r
+void   _sethosthtent(int);\r
+void   _endhosthtent(void);\r
+void   _sethostdnsent(int);\r
+void   _endhostdnsent(void);\r
+void   _setnethtent(int);\r
+void   _endnethtent(void);\r
+void   _setnetdnsent(int);\r
+void   _endnetdnsent(void);\r
+\r
+struct hostent * _gethostbyhtname(const char *, int);\r
+struct hostent * _gethostbydnsname(const char *, int);\r
+struct hostent * _gethostbynisname(const char *, int);\r
+struct hostent * _gethostbyhtaddr(const char *, int, int);\r
+struct hostent * _gethostbydnsaddr(const char *, int, int);\r
+struct hostent * _gethostbynisaddr(const char *, int, int);\r
+struct netent *  _getnetbyhtname(const char *);\r
+struct netent *  _getnetbydnsname(const char *);\r
+struct netent *  _getnetbynisname(const char *);\r
+struct netent *  _getnetbyhtaddr(unsigned long, int);\r
+struct netent *  _getnetbydnsaddr(unsigned long, int);\r
+struct netent *  _getnetbynisaddr(unsigned long, int);\r
+void _map_v4v6_address(const char *src, char *dst);\r
+void _map_v4v6_hostent(struct hostent *hp, char **bp, int *len);\r
+#endif\r
+\r
diff --git a/StdLib/BsdSocketLib/accept.c b/StdLib/BsdSocketLib/accept.c
new file mode 100644 (file)
index 0000000..3dbfe97
--- /dev/null
@@ -0,0 +1,157 @@
+/** @file\r
+  Implement the accept API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Worker routine for ::Accept and ::AcceptNB\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] bBlocking TRUE if this is a blocking call\r
+  @param [in] address   Address of a buffer to receive the remote network address.\r
+\r
+  @param [in, out] address_len  Address of a buffer containing the Length in bytes\r
+                                of the remote network address buffer.  Upon return,\r
+                                contains the length of the remote network address.\r
+\r
+  @returns    ::accept returns zero if successful and -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+int\r
+AcceptWork (\r
+  int s,\r
+  BOOLEAN bBlocking,\r
+  struct sockaddr * address,\r
+  socklen_t * address_len\r
+  )\r
+{\r
+  INT32 NewSocketFd;\r
+  struct __filedes * pDescriptor;\r
+  EFI_SOCKET_PROTOCOL * pNewSocket;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  NewSocketFd = -1;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s,\r
+                                            &pDescriptor,\r
+                                            &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    // TODO: Update bBlocking by anding with check for NON_BLOCKING\r
+    //\r
+    \r
+    //\r
+    //  Attempt to accept a new network connection\r
+    //\r
+    do {\r
+      Status = pSocketProtocol->pfnAccept ( pSocketProtocol,\r
+                                            address,\r
+                                            address_len,\r
+                                            &pNewSocket,\r
+                                            &errno );\r
+    } while ( bBlocking && ( EFI_NOT_READY == Status ));\r
+\r
+    //\r
+    //  Convert the protocol to a socket\r
+    //\r
+    NewSocketFd = BslSocketProtocolToFd ( pNewSocket, &errno );\r
+    if ( -1 == NewSocketFd ) {\r
+      //\r
+      //  Close the socket\r
+      //\r
+      BslSocketCloseWork ( pNewSocket, NULL );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the new socket file descriptor\r
+  //\r
+  return NewSocketFd;\r
+}\r
+\r
+\r
+/**\r
+  Accept a network connection.\r
+\r
+  The ::accept routine waits for a network connection to the socket.\r
+  It is able to return the remote network address to the caller if\r
+  requested.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] address   Address of a buffer to receive the remote network address.\r
+\r
+  @param [in, out] address_len  Address of a buffer containing the Length in bytes\r
+                                of the remote network address buffer.  Upon return,\r
+                                contains the length of the remote network address.\r
+\r
+  @returns    ::accept returns zero if successful and -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+int\r
+accept (\r
+  int s,\r
+  struct sockaddr * address,\r
+  socklen_t * address_len\r
+  )\r
+{\r
+  //\r
+  //  Wait for the accept call to complete\r
+  //\r
+  return AcceptWork ( s, TRUE, address, address_len );\r
+}\r
+\r
+\r
+/**\r
+  Non blocking version of accept.\r
+\r
+  See ::accept\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] address   Address of a buffer to receive the remote network address.\r
+\r
+  @param [in, out] address_len  Address of a buffer containing the Length in bytes\r
+                                of the remote network address buffer.  Upon return,\r
+                                contains the length of the remote network address.\r
+\r
+  @returns    This routine returns zero if successful and -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+int\r
+AcceptNB (\r
+  int s,\r
+  struct sockaddr * address,\r
+  socklen_t * address_len\r
+  )\r
+{\r
+  //\r
+  //  Attempt to accept a network connection\r
+  //\r
+  return AcceptWork ( s, FALSE, address, address_len );\r
+}\r
diff --git a/StdLib/BsdSocketLib/base64.c b/StdLib/BsdSocketLib/base64.c
new file mode 100644 (file)
index 0000000..5933605
--- /dev/null
@@ -0,0 +1,357 @@
+/*\r
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.\r
+ *\r
+ * International Business Machines, Inc. (hereinafter called IBM) grants\r
+ * permission under its copyrights to use, copy, modify, and distribute this\r
+ * Software with or without fee, provided that the above copyright notice and\r
+ * all paragraphs of this notice appear in all copies, and that the name of IBM\r
+ * not be used in connection with the marketing of any product incorporating\r
+ * the Software or modifications thereof, without specific, written prior\r
+ * permission.\r
+ *\r
+ * To the extent it has a right to do so, IBM grants an immunity from suit\r
+ * under its patents, if any, for the use, sale or manufacture of products to\r
+ * the extent that such products are used for performing Domain Name System\r
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is\r
+ * granted for any product per se or for any other function of any product.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,\r
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,\r
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING\r
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN\r
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#if !defined(LINT) && !defined(CODECENTER)\r
+static char rcsid[] = "$Id: base64.c,v 1.1.1.1 2003/11/19 01:51:25 kyu3 Exp $";\r
+#endif /* not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+\r
+#include <ctype.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#define Assert(Cond) if (!(Cond)) abort()\r
+\r
+static const char Base64[] =\r
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\r
+static const char Pad64 = '=';\r
+\r
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)\r
+   The following encoding technique is taken from RFC 1521 by Borenstein\r
+   and Freed.  It is reproduced here in a slightly edited form for\r
+   convenience.\r
+\r
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be\r
+   represented per printable character. (The extra 65th character, "=",\r
+   is used to signify a special processing function.)\r
+\r
+   The encoding process represents 24-bit groups of input bits as output\r
+   strings of 4 encoded characters. Proceeding from left to right, a\r
+   24-bit input group is formed by concatenating 3 8-bit input groups.\r
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each\r
+   of which is translated into a single digit in the base64 alphabet.\r
+\r
+   Each 6-bit group is used as an index into an array of 64 printable\r
+   characters. The character referenced by the index is placed in the\r
+   output string.\r
+\r
+                         Table 1: The Base64 Alphabet\r
+\r
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding\r
+          0 A            17 R            34 i            51 z\r
+          1 B            18 S            35 j            52 0\r
+          2 C            19 T            36 k            53 1\r
+          3 D            20 U            37 l            54 2\r
+          4 E            21 V            38 m            55 3\r
+          5 F            22 W            39 n            56 4\r
+          6 G            23 X            40 o            57 5\r
+          7 H            24 Y            41 p            58 6\r
+          8 I            25 Z            42 q            59 7\r
+          9 J            26 a            43 r            60 8\r
+         10 K            27 b            44 s            61 9\r
+         11 L            28 c            45 t            62 +\r
+         12 M            29 d            46 u            63 /\r
+         13 N            30 e            47 v\r
+         14 O            31 f            48 w         (pad) =\r
+         15 P            32 g            49 x\r
+         16 Q            33 h            50 y\r
+\r
+   Special processing is performed if fewer than 24 bits are available\r
+   at the end of the data being encoded.  A full encoding quantum is\r
+   always completed at the end of a quantity.  When fewer than 24 input\r
+   bits are available in an input group, zero bits are added (on the\r
+   right) to form an integral number of 6-bit groups.  Padding at the\r
+   end of the data is performed using the '=' character.\r
+\r
+   Since all base64 input is an integral number of octets, only the\r
+         -------------------------------------------------                       \r
+   following cases can arise:\r
+   \r
+       (1) the final quantum of encoding input is an integral\r
+           multiple of 24 bits; here, the final unit of encoded\r
+          output will be an integral multiple of 4 characters\r
+          with no "=" padding,\r
+       (2) the final quantum of encoding input is exactly 8 bits;\r
+           here, the final unit of encoded output will be two\r
+          characters followed by two "=" padding characters, or\r
+       (3) the final quantum of encoding input is exactly 16 bits;\r
+           here, the final unit of encoded output will be three\r
+          characters followed by one "=" padding character.\r
+   */\r
+\r
+int\r
+b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {\r
+       size_t datalength = 0;\r
+       u_char input[3];\r
+       u_char output[4];\r
+       size_t i;\r
+\r
+       while (2 < srclength) {\r
+               input[0] = *src++;\r
+               input[1] = *src++;\r
+               input[2] = *src++;\r
+               srclength -= 3;\r
+\r
+               output[0] = input[0] >> 2;\r
+               output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);\r
+               output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);\r
+               output[3] = input[2] & 0x3f;\r
+               Assert(output[0] < 64);\r
+               Assert(output[1] < 64);\r
+               Assert(output[2] < 64);\r
+               Assert(output[3] < 64);\r
+\r
+               if (datalength + 4 > targsize)\r
+                       return (-1);\r
+               target[datalength++] = Base64[output[0]];\r
+               target[datalength++] = Base64[output[1]];\r
+               target[datalength++] = Base64[output[2]];\r
+               target[datalength++] = Base64[output[3]];\r
+       }\r
+    \r
+       /* Now we worry about padding. */\r
+       if (0 != srclength) {\r
+               /* Get what's left. */\r
+               input[0] = input[1] = input[2] = '\0';\r
+               for (i = 0; i < srclength; i++)\r
+                       input[i] = *src++;\r
+       \r
+               output[0] = input[0] >> 2;\r
+               output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);\r
+               output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);\r
+               Assert(output[0] < 64);\r
+               Assert(output[1] < 64);\r
+               Assert(output[2] < 64);\r
+\r
+               if (datalength + 4 > targsize)\r
+                       return (-1);\r
+               target[datalength++] = Base64[output[0]];\r
+               target[datalength++] = Base64[output[1]];\r
+               if (srclength == 1)\r
+                       target[datalength++] = Pad64;\r
+               else\r
+                       target[datalength++] = Base64[output[2]];\r
+               target[datalength++] = Pad64;\r
+       }\r
+       if (datalength >= targsize)\r
+               return (-1);\r
+       target[datalength] = '\0';      /* Returned value doesn't count \0. */\r
+       return ((int)datalength);\r
+}\r
+\r
+/* skips all whitespace anywhere.\r
+   converts characters, four at a time, starting at (or after)\r
+   src from base - 64 numbers into three 8 bit bytes in the target area.\r
+   it returns the number of data bytes stored at the target, or -1 on error.\r
+ */\r
+\r
+int\r
+b64_pton(\r
+       char const *src,\r
+       u_char *target,\r
+       size_t targsize\r
+       )\r
+{\r
+       int tarindex, state, ch;\r
+       char *pos;\r
+\r
+       state = 0;\r
+       tarindex = 0;\r
+\r
+       while ((ch = *src++) != '\0') {\r
+               if (isspace(ch))        /* Skip whitespace anywhere. */\r
+                       continue;\r
+\r
+               if (ch == Pad64)\r
+                       break;\r
+\r
+               pos = strchr(Base64, ch);\r
+               if (pos == 0)           /* A non-base64 character. */\r
+                       return (-1);\r
+\r
+               switch (state) {\r
+               case 0:\r
+                       if (target) {\r
+                               if ((size_t)tarindex >= targsize)\r
+                                       return (-1);\r
+                               target[tarindex] = (u_char)((pos - Base64) << 2);\r
+                       }\r
+                       state = 1;\r
+                       break;\r
+               case 1:\r
+                       if (target) {\r
+                               if ((size_t)tarindex + 1 >= targsize)\r
+                                       return (-1);\r
+                               target[tarindex]   |= (u_char)((pos - Base64) >> 4);\r
+                               target[tarindex+1]  = (u_char)(((pos - Base64) & 0x0f)\r
+                                                       << 4) ;\r
+                       }\r
+                       tarindex++;\r
+                       state = 2;\r
+                       break;\r
+               case 2:\r
+                       if (target) {\r
+                               if ((size_t)tarindex + 1 >= targsize)\r
+                                       return (-1);\r
+                               target[tarindex]   |= (u_char)((pos - Base64) >> 2);\r
+                               target[tarindex+1]  = (u_char)(((pos - Base64) & 0x03)\r
+                                                       << 6);\r
+                       }\r
+                       tarindex++;\r
+                       state = 3;\r
+                       break;\r
+               case 3:\r
+                       if (target) {\r
+                               if ((size_t)tarindex >= targsize)\r
+                                       return (-1);\r
+                               target[tarindex] |= (u_char)(pos - Base64);\r
+                       }\r
+                       tarindex++;\r
+                       state = 0;\r
+                       break;\r
+               default:\r
+                       abort();\r
+               }\r
+       }\r
+\r
+       /*\r
+        * We are done decoding Base-64 chars.  Let's see if we ended\r
+        * on a byte boundary, and/or with erroneous trailing characters.\r
+        */\r
+\r
+       if (ch == Pad64) {              /* We got a pad char. */\r
+               ch = *src++;            /* Skip it, get next. */\r
+               switch (state) {\r
+               case 0:         /* Invalid = in first position */\r
+               case 1:         /* Invalid = in second position */\r
+                       return (-1);\r
+\r
+               case 2:         /* Valid, means one byte of info */\r
+                       /* Skip any number of spaces. */\r
+                       for ((void)NULL; ch != '\0'; ch = *src++)\r
+                               if (!isspace(ch))\r
+                                       break;\r
+                       /* Make sure there is another trailing = sign. */\r
+                       if (ch != Pad64)\r
+                               return (-1);\r
+                       ch = *src++;            /* Skip the = */\r
+                       /* Fall through to "single trailing =" case. */\r
+                       /* FALLTHROUGH */\r
+\r
+               case 3:         /* Valid, means two bytes of info */\r
+                       /*\r
+                        * We know this char is an =.  Is there anything but\r
+                        * whitespace after it?\r
+                        */\r
+                       for ((void)NULL; ch != '\0'; ch = *src++)\r
+                               if (!isspace(ch))\r
+                                       return (-1);\r
+\r
+                       /*\r
+                        * Now make sure for cases 2 and 3 that the "extra"\r
+                        * bits that slopped past the last full byte were\r
+                        * zeros.  If we don't check them, they become a\r
+                        * subliminal channel.\r
+                        */\r
+                       if (target && target[tarindex] != 0)\r
+                               return (-1);\r
+               }\r
+       } else {\r
+               /*\r
+                * We ended by seeing the end of the string.  Make sure we\r
+                * have no partial bytes lying around.\r
+                */\r
+               if (state != 0)\r
+                       return (-1);\r
+       }\r
+\r
+       return (tarindex);\r
+}\r
diff --git a/StdLib/BsdSocketLib/bind.c b/StdLib/BsdSocketLib/bind.c
new file mode 100644 (file)
index 0000000..fc24ea4
--- /dev/null
@@ -0,0 +1,72 @@
+/** @file\r
+  Implement the bind API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Bind a name to a socket.\r
+\r
+  The ::bind routine connects a name to a socket on the local machine.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html">POSIX</a>\r
+  documentation for the bind routine is available online for reference.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] name      Address of a sockaddr structure that contains the\r
+                        connection point on the local machine.  An IPv4 address\r
+                        of INADDR_ANY specifies that the connection is made to\r
+                        all of the network stacks on the platform.  Specifying a\r
+                        specific IPv4 address restricts the connection to the\r
+                        network stack supporting that address.  Specifying zero\r
+                        for the port causes the network layer to assign a port\r
+                        number from the dynamic range.  Specifying a specific\r
+                        port number causes the network layer to use that port.\r
+\r
+  @param [in] namelen   Specifies the length in bytes of the sockaddr structure.\r
+\r
+  @returns    The bind routine returns zero (0) if successful and -1 upon failure.\r
+\r
+ **/\r
+int\r
+bind (\r
+  IN int s,\r
+  IN const struct sockaddr * name,\r
+  IN socklen_t namelen\r
+  )\r
+{\r
+  int BindStatus;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Bind the socket\r
+    //\r
+    Status = pSocketProtocol->pfnBind ( pSocketProtocol,\r
+                                        name,\r
+                                        namelen,\r
+                                        &errno );\r
+  }\r
+\r
+  //\r
+  //  Return the operation stauts\r
+  //\r
+  BindStatus = ( 0 == errno ) ? 0 : -1;\r
+  return BindStatus;\r
+}\r
diff --git a/StdLib/BsdSocketLib/close.c b/StdLib/BsdSocketLib/close.c
new file mode 100644 (file)
index 0000000..7d70e4f
--- /dev/null
@@ -0,0 +1,116 @@
+/** @file\r
+  Implement the close API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Worker routine to close the socket.\r
+\r
+  @param [in] pSocketProtocol   Socket protocol structure address\r
+\r
+  @param [in] pErrno            Address of the errno variable\r
+\r
+  @retval EFI_SUCCESS   Successfully closed the socket\r
+\r
+**/\r
+EFI_STATUS\r
+BslSocketCloseWork (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Start closing the socket\r
+  //\r
+  Status = pSocketProtocol->pfnCloseStart ( pSocketProtocol,\r
+                                            FALSE,\r
+                                            pErrno );\r
+\r
+  //\r
+  //  Wait for the socket to close or an error\r
+  //\r
+  while ( EFI_NOT_READY == Status ) {\r
+    Status = pSocketProtocol->pfnClosePoll ( pSocketProtocol,\r
+                                             pErrno );\r
+  }\r
+  if ( !EFI_ERROR ( Status )) {\r
+    //\r
+    //  Locate the socket protocol\r
+    //\r
+    Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,\r
+                                   NULL,\r
+                                   (VOID **) &pServiceBinding );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Release the handle\r
+      //\r
+      Status = pServiceBinding->DestroyChild ( pServiceBinding,\r
+                                               pSocketProtocol->SocketHandle );\r
+    }\r
+    if ( EFI_ERROR ( Status )) {\r
+      *pErrno = EIO;\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_ERROR,\r
+              "ERROR - Failed to close the socket: %r\r\n",\r
+              Status ));\r
+    *pErrno = EIO;\r
+  }\r
+\r
+  //\r
+  //  Return the close status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Close the socket\r
+\r
+  @param [in] pDescriptor Descriptor address for the file\r
+\r
+  @returns  This routine returns 0 upon success and -1 upon failure.\r
+            In the case of failure, errno contains more information.\r
+\r
+**/\r
+int\r
+BslSocketClose (\r
+  struct __filedes * pDescriptor\r
+  )\r
+{\r
+  int CloseStatus;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+\r
+  //\r
+  //  Locate the socket protocol\r
+  //\r
+  pSocketProtocol = BslValidateSocketFd ( pDescriptor, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Close the socket\r
+    //\r
+    BslSocketCloseWork ( pSocketProtocol, &errno );\r
+  }\r
+\r
+  //\r
+  //  Return the close status\r
+  //\r
+  CloseStatus = ( errno == 0 ) ? 0 : -1;\r
+  return CloseStatus;\r
+}\r
diff --git a/StdLib/BsdSocketLib/connect.c b/StdLib/BsdSocketLib/connect.c
new file mode 100644 (file)
index 0000000..e02762e
--- /dev/null
@@ -0,0 +1,94 @@
+/** @file\r
+  Implement the connect API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Connect to a remote system via the network.\r
+\r
+  The ::connect routine attempts to establish a connection to a\r
+  socket on the local or remote system using the specified address.\r
+  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  There are three states associated with a connection:\r
+  <ul>\r
+    <li>Not connected</li>\r
+    <li>Connection in progress</li>\r
+    <li>Connected</li>\r
+  </ul>\r
+  In the "Not connected" state, calls to ::connect start the connection\r
+  processing and update the state to "Connection in progress".  During\r
+  the "Connection in progress" state, connect polls for connection completion\r
+  and moves the state to "Connected" after the connection is established.\r
+  Note that these states are only visible when the file descriptor is marked\r
+  with O_NONBLOCK.  Also, the POLL_WRITE bit is set when the connection\r
+  completes and may be used by poll or select as an indicator to call\r
+  connect again.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] address   Network address of the remote system\r
+  \r
+  @param [in] address_len Length of the remote network address\r
+\r
+  @returns    ::connect returns zero if successful and -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+int\r
+connect (\r
+  int s,\r
+  const struct sockaddr * address,\r
+  socklen_t address_len\r
+  )\r
+{\r
+  BOOLEAN bBlocking;\r
+  int ConnectStatus;\r
+  struct __filedes * pDescriptor;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+  \r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s,\r
+                                            &pDescriptor,\r
+                                            &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    // TODO: Check for NON_BLOCKING\r
+    //\r
+    bBlocking = TRUE;\r
+\r
+    //\r
+    //  Attempt to connect to a remote system\r
+    //\r
+    do {\r
+      errno = 0;\r
+      Status = pSocketProtocol->pfnConnect ( pSocketProtocol,\r
+                                             address,\r
+                                             address_len,\r
+                                             &errno );\r
+    } while ( bBlocking && ( EFI_NOT_READY == Status ));\r
+  }\r
+  \r
+  //\r
+  //  Return the new socket file descriptor\r
+  //\r
+  ConnectStatus = (0 == errno) ? 0 : -1;\r
+  return ConnectStatus;\r
+}\r
diff --git a/StdLib/BsdSocketLib/errno.c b/StdLib/BsdSocketLib/errno.c
new file mode 100644 (file)
index 0000000..360609b
--- /dev/null
@@ -0,0 +1,18 @@
+/** @file\r
+  errno variable\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <sys/errno.h>\r
+\r
+\r
+int errno;\r
diff --git a/StdLib/BsdSocketLib/gethostbydns.c b/StdLib/BsdSocketLib/gethostbydns.c
new file mode 100644 (file)
index 0000000..25e7c3b
--- /dev/null
@@ -0,0 +1,814 @@
+/*\r
+ * ++Copyright++ 1985, 1988, 1993\r
+ * -\r
+ * Copyright (c) 1985, 1988, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ * -\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ * -\r
+ * --Copyright--\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)gethostnamadr.c    8.1 (Berkeley) 6/4/93";\r
+static char fromrcsid[] = "From: Id: gethnamaddr.c,v 8.23 1998/04/07 04:59:46 vixie Exp $";\r
+static char rcsid[] = "$Id: gethostbydns.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+\r
+#include <stdio.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#ifdef _ORG_FREEBSD_\r
+#include <syslog.h>\r
+#else\r
+#include <stdlib.h>\r
+u_int32_t _getlong(const u_char *src);\r
+u_int16_t _getshort(const u_char *src);\r
+#endif\r
+\r
+#include "res_config.h"\r
+#include "Socklib_internals.h"\r
+\r
+#define SPRINTF(x) ((size_t)sprintf x)\r
+\r
+#define        MAXALIASES      35\r
+#define        MAXADDRS        35\r
+\r
+static const char AskedForGot[] =\r
+               "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";\r
+\r
+static char *h_addr_ptrs[MAXADDRS + 1];\r
+\r
+static struct hostent host;\r
+static char *host_aliases[MAXALIASES];\r
+static char hostbuf[8*1024];\r
+static u_char host_addr[16];   /* IPv4 or IPv6 */\r
+\r
+#ifdef RESOLVSORT\r
+static void addrsort(char **, int);\r
+#endif\r
+\r
+#if PACKETSZ > 1024\r
+#define        MAXPACKET       PACKETSZ\r
+#else\r
+#define        MAXPACKET       1024\r
+#endif\r
+\r
+typedef union {\r
+    HEADER hdr;\r
+    u_char buf[MAXPACKET];\r
+} querybuf;\r
+\r
+typedef union {\r
+    int32_t al;\r
+    char ac;\r
+} align;\r
+\r
+extern int h_errno;\r
+int _dns_ttl_;\r
+\r
+#ifdef DEBUG_RES\r
+static void\r
+dprintf(char *msg, int num)\r
+{\r
+       if (_res.options & RES_DEBUG) {\r
+               int save = errno;\r
+\r
+               printf(msg, num);\r
+               errno = save;\r
+       }\r
+}\r
+#else\r
+# define dprintf(msg, num) /*nada*/\r
+#endif\r
+\r
+#define BOUNDED_INCR(x) \\r
+       do { \\r
+               cp += x; \\r
+               if (cp > eom) { \\r
+                       h_errno = NO_RECOVERY; \\r
+                       return (NULL); \\r
+               } \\r
+       } while (0)\r
+\r
+#define BOUNDS_CHECK(ptr, count) \\r
+       do { \\r
+               if ((ptr) + (count) > eom) { \\r
+                       h_errno = NO_RECOVERY; \\r
+                       return (NULL); \\r
+               } \\r
+       } while (0)\r
+\r
+static struct hostent *\r
+gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype)\r
+{\r
+       register const HEADER *hp;\r
+       register const u_char *cp;\r
+       register int n;\r
+       const u_char *eom, *erdata;\r
+       char *bp, **ap, **hap;\r
+       int type, class, buflen, ancount, qdcount;\r
+       int haveanswer, had_error;\r
+       int toobig = 0;\r
+       char tbuf[MAXDNAME];\r
+       const char *tname;\r
+       int (*name_ok)(const char *);\r
+\r
+       tname = qname;\r
+       host.h_name = NULL;\r
+       eom = answer->buf + anslen;\r
+       switch (qtype) {\r
+       case T_A:\r
+       case T_AAAA:\r
+               name_ok = res_hnok;\r
+               break;\r
+       case T_PTR:\r
+               name_ok = res_dnok;\r
+               break;\r
+       default:\r
+               h_errno = NO_RECOVERY;\r
+               return (NULL);  /* XXX should be abort(); */\r
+       }\r
+       /*\r
+        * find first satisfactory answer\r
+        */\r
+       hp = &answer->hdr;\r
+       ancount = ntohs(hp->ancount);\r
+       qdcount = ntohs(hp->qdcount);\r
+       bp = hostbuf;\r
+       buflen = sizeof hostbuf;\r
+       cp = answer->buf;\r
+       BOUNDED_INCR(HFIXEDSZ);\r
+       if (qdcount != 1) {\r
+               h_errno = NO_RECOVERY;\r
+               return (NULL);\r
+       }\r
+       n = dn_expand(answer->buf, eom, cp, bp, buflen);\r
+       if ((n < 0) || !(*name_ok)(bp)) {\r
+               h_errno = NO_RECOVERY;\r
+               return (NULL);\r
+       }\r
+       BOUNDED_INCR(n + QFIXEDSZ);\r
+       if (qtype == T_A || qtype == T_AAAA) {\r
+               /* res_send() has already verified that the query name is the\r
+                * same as the one we sent; this just gets the expanded name\r
+                * (i.e., with the succeeding search-domain tacked on).\r
+                */\r
+               n = (int)strlen(bp) + 1;                /* for the \0 */\r
+               if (n >= MAXHOSTNAMELEN) {\r
+                       h_errno = NO_RECOVERY;\r
+                       return (NULL);\r
+               }\r
+               host.h_name = bp;\r
+               bp += n;\r
+               buflen -= n;\r
+               /* The qname can be abbreviated, but h_name is now absolute. */\r
+               qname = host.h_name;\r
+       }\r
+       ap = host_aliases;\r
+       *ap = NULL;\r
+       host.h_aliases = host_aliases;\r
+       hap = h_addr_ptrs;\r
+       *hap = NULL;\r
+       host.h_addr_list = h_addr_ptrs;\r
+       haveanswer = 0;\r
+       had_error = 0;\r
+       _dns_ttl_ = -1;\r
+       while (ancount-- > 0 && cp < eom && !had_error) {\r
+               n = dn_expand(answer->buf, eom, cp, bp, buflen);\r
+               if ((n < 0) || !(*name_ok)(bp)) {\r
+                       had_error++;\r
+                       continue;\r
+               }\r
+               cp += n;                        /* name */\r
+               BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);\r
+               type = _getshort(cp);\r
+               cp += INT16SZ;                  /* type */\r
+               class = _getshort(cp);\r
+               cp += INT16SZ;                  /* class */\r
+               if (qtype == T_A  && type == T_A)\r
+                       _dns_ttl_ = _getlong(cp);\r
+               cp += INT32SZ;                  /* TTL */\r
+               n = _getshort(cp);\r
+               cp += INT16SZ;                  /* len */\r
+               BOUNDS_CHECK(cp, n);\r
+               erdata = cp + n;\r
+               if (class != C_IN) {\r
+                       /* XXX - debug? syslog? */\r
+                       cp += n;\r
+                       continue;               /* XXX - had_error++ ? */\r
+               }\r
+               if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {\r
+                       if (ap >= &host_aliases[MAXALIASES-1])\r
+                               continue;\r
+                       n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);\r
+                       if ((n < 0) || !(*name_ok)(tbuf)) {\r
+                               had_error++;\r
+                               continue;\r
+                       }\r
+                       cp += n;\r
+                       if (cp != erdata) {\r
+                               h_errno = NO_RECOVERY;\r
+                               return (NULL);\r
+                       }\r
+                       /* Store alias. */\r
+                       *ap++ = bp;\r
+                       n = (int)strlen(bp) + 1;        /* for the \0 */\r
+                       if (n >= MAXHOSTNAMELEN) {\r
+                               had_error++;\r
+                               continue;\r
+                       }\r
+                       bp += n;\r
+                       buflen -= n;\r
+                       /* Get canonical name. */\r
+                       n = (int)strlen(tbuf) + 1;      /* for the \0 */\r
+                       if (n > buflen || n >= MAXHOSTNAMELEN) {\r
+                               had_error++;\r
+                               continue;\r
+                       }\r
+                       strcpy(bp, tbuf);\r
+                       host.h_name = bp;\r
+                       bp += n;\r
+                       buflen -= n;\r
+                       continue;\r
+               }\r
+               if (qtype == T_PTR && type == T_CNAME) {\r
+                       n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);\r
+                       if (n < 0 || !res_dnok(tbuf)) {\r
+                               had_error++;\r
+                               continue;\r
+                       }\r
+                       cp += n;\r
+                       if (cp != erdata) {\r
+                               h_errno = NO_RECOVERY;\r
+                               return (NULL);\r
+                       }\r
+                       /* Get canonical name. */\r
+                       n = (int)strlen(tbuf) + 1;      /* for the \0 */\r
+                       if (n > buflen || n >= MAXHOSTNAMELEN) {\r
+                               had_error++;\r
+                               continue;\r
+                       }\r
+                       strcpy(bp, tbuf);\r
+                       tname = bp;\r
+                       bp += n;\r
+                       buflen -= n;\r
+                       continue;\r
+               }\r
+               if (type != qtype) {\r
+#ifdef _ORG_FREEBSD_\r
+                       syslog(LOG_NOTICE|LOG_AUTH,\r
+       "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",\r
+                              qname, p_class(C_IN), p_type(qtype),\r
+                              p_type(type));\r
+#endif\r
+                       cp += n;\r
+                       continue;               /* XXX - had_error++ ? */\r
+               }\r
+               switch (type) {\r
+               case T_PTR:\r
+                       if (strcasecmp(tname, bp) != 0) {\r
+#ifdef _ORG_FREEBSD_\r
+                               syslog(LOG_NOTICE|LOG_AUTH,\r
+                                      AskedForGot, qname, bp);\r
+#endif\r
+                               cp += n;\r
+                               continue;       /* XXX - had_error++ ? */\r
+                       }\r
+                       n = dn_expand(answer->buf, eom, cp, bp, buflen);\r
+                       if ((n < 0) || !res_hnok(bp)) {\r
+                               had_error++;\r
+                               break;\r
+                       }\r
+#if MULTI_PTRS_ARE_ALIASES\r
+                       cp += n;\r
+                       if (cp != erdata) {\r
+                               h_errno = NO_RECOVERY;\r
+                               return (NULL);\r
+                       }\r
+                       if (!haveanswer)\r
+                               host.h_name = bp;\r
+                       else if (ap < &host_aliases[MAXALIASES-1])\r
+                               *ap++ = bp;\r
+                       else\r
+                               n = -1;\r
+                       if (n != -1) {\r
+                               n = (int)strlen(bp) + 1;        /* for the \0 */\r
+                               if (n >= MAXHOSTNAMELEN) {\r
+                                       had_error++;\r
+                                       break;\r
+                               }\r
+                               bp += n;\r
+                               buflen -= n;\r
+                       }\r
+                       break;\r
+#else\r
+                       host.h_name = bp;\r
+                       if (_res.options & RES_USE_INET6) {\r
+                               n = strlen(bp) + 1;     /* for the \0 */\r
+                               if (n >= MAXHOSTNAMELEN) {\r
+                                       had_error++;\r
+                                       break;\r
+                               }\r
+                               bp += n;\r
+                               buflen -= n;\r
+                               _map_v4v6_hostent(&host, &bp, &buflen);\r
+                       }\r
+                       h_errno = NETDB_SUCCESS;\r
+                       return (&host);\r
+#endif\r
+               case T_A:\r
+               case T_AAAA:\r
+                       if (strcasecmp(host.h_name, bp) != 0) {\r
+#ifdef _ORG_FREEBSD_\r
+                               syslog(LOG_NOTICE|LOG_AUTH,\r
+                                      AskedForGot, host.h_name, bp);\r
+#endif\r
+                               cp += n;\r
+                               continue;       /* XXX - had_error++ ? */\r
+                       }\r
+                       if (n != host.h_length) {\r
+                               cp += n;\r
+                               continue;\r
+                       }\r
+                       if (!haveanswer) {\r
+                               register int nn;\r
+\r
+                               host.h_name = bp;\r
+                               nn = (int)strlen(bp) + 1;       /* for the \0 */\r
+                               bp += nn;\r
+                               buflen -= nn;\r
+                       }\r
+\r
+                       bp += sizeof(align) - ((size_t)bp % sizeof(align));\r
+\r
+                       if (bp + n >= &hostbuf[sizeof hostbuf]) {\r
+                               dprintf("size (%d) too big\n", n);\r
+                               had_error++;\r
+                               continue;\r
+                       }\r
+                       if (hap >= &h_addr_ptrs[MAXADDRS-1]) {\r
+                               if (!toobig++)\r
+                                       dprintf("Too many addresses (%d)\n",\r
+                                               MAXADDRS);\r
+                               cp += n;\r
+                               continue;\r
+                       }\r
+      *hap++ = bp;\r
+                       bcopy(cp, bp, n);\r
+                       bp += n;\r
+                       buflen -= n;\r
+                       cp += n;\r
+                       if (cp != erdata) {\r
+                               h_errno = NO_RECOVERY;\r
+                               return (NULL);\r
+                       }\r
+                       break;\r
+               default:\r
+                       dprintf("Impossible condition (type=%d)\n", type);\r
+                       h_errno = NO_RECOVERY;\r
+                       return (NULL);\r
+                       /* BIND has abort() here, too risky on bad data */\r
+               }\r
+               if (!had_error)\r
+                       haveanswer++;\r
+       }\r
+       if (haveanswer) {\r
+               *ap = NULL;\r
+               *hap = NULL;\r
+# if defined(RESOLVSORT)\r
+               /*\r
+                * Note: we sort even if host can take only one address\r
+                * in its return structures - should give it the "best"\r
+                * address in that case, not some random one\r
+                */\r
+               if (_res.nsort && haveanswer > 1 && qtype == T_A)\r
+                       addrsort(h_addr_ptrs, haveanswer);\r
+# endif /*RESOLVSORT*/\r
+               if (!host.h_name) {\r
+                       n = (int)strlen(qname) + 1;     /* for the \0 */\r
+                       if (n > buflen || n >= MAXHOSTNAMELEN)\r
+                               goto no_recovery;\r
+                       strcpy(bp, qname);\r
+                       host.h_name = bp;\r
+                       bp += n;\r
+                       buflen -= n;\r
+               }\r
+               if (_res.options & RES_USE_INET6)\r
+                       _map_v4v6_hostent(&host, &bp, &buflen);\r
+               h_errno = NETDB_SUCCESS;\r
+               return (&host);\r
+       }\r
+ no_recovery:\r
+       h_errno = NO_RECOVERY;\r
+       return (NULL);\r
+}\r
+\r
+struct hostent *\r
+__dns_getanswer(const char *answer, int anslen, const char *qname, int qtype)\r
+{\r
+       switch(qtype) {\r
+       case T_AAAA:\r
+               host.h_addrtype = AF_INET6;\r
+               host.h_length = IN6ADDRSZ;\r
+               break;\r
+       case T_A:\r
+       default:\r
+               host.h_addrtype = AF_INET;\r
+               host.h_length = INADDRSZ;\r
+               break;\r
+       }\r
+\r
+       return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));\r
+}\r
+\r
+struct hostent *\r
+_gethostbydnsname(const char *name, int af)\r
+{\r
+       querybuf buf;\r
+       register const char *cp;\r
+       char *bp;\r
+       int n, size, type, len;\r
+\r
+       if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+               h_errno = NETDB_INTERNAL;\r
+               return (NULL);\r
+       }\r
+\r
+       switch (af) {\r
+       case AF_INET:\r
+               size = INADDRSZ;\r
+               type = T_A;\r
+               break;\r
+       case AF_INET6:\r
+               size = IN6ADDRSZ;\r
+               type = T_AAAA;\r
+               break;\r
+       default:\r
+               h_errno = NETDB_INTERNAL;\r
+               errno = EAFNOSUPPORT;\r
+               return (NULL);\r
+       }\r
+\r
+       host.h_addrtype = af;\r
+       host.h_length = size;\r
+\r
+       /*\r
+        * if there aren't any dots, it could be a user-level alias.\r
+        * this is also done in res_query() since we are not the only\r
+        * function that looks up host names.\r
+        */\r
+       if (!strchr(name, '.') && ( NULL != (cp = __hostalias(name))))\r
+               name = cp;\r
+\r
+       /*\r
+        * disallow names consisting only of digits/dots, unless\r
+        * they end in a dot.\r
+        */\r
+       if (isdigit(name[0]))\r
+               for (cp = name;; ++cp) {\r
+                       if (!*cp) {\r
+                               if (*--cp == '.')\r
+                                       break;\r
+                               /*\r
+                                * All-numeric, no dot at the end.\r
+                                * Fake up a hostent as if we'd actually\r
+                                * done a lookup.\r
+                                */\r
+                               if (inet_pton(af, name, host_addr) <= 0) {\r
+                                       h_errno = HOST_NOT_FOUND;\r
+                                       return (NULL);\r
+                               }\r
+                               strncpy(hostbuf, name, MAXDNAME);\r
+                               hostbuf[MAXDNAME] = '\0';\r
+                               bp = hostbuf + MAXDNAME;\r
+                               len = sizeof hostbuf - MAXDNAME;\r
+                               host.h_name = hostbuf;\r
+                               host.h_aliases = host_aliases;\r
+                               host_aliases[0] = NULL;\r
+                               h_addr_ptrs[0] = (char *)host_addr;\r
+                               h_addr_ptrs[1] = NULL;\r
+                               host.h_addr_list = h_addr_ptrs;\r
+                               if (_res.options & RES_USE_INET6)\r
+                                       _map_v4v6_hostent(&host, &bp, &len);\r
+                               h_errno = NETDB_SUCCESS;\r
+                               return (&host);\r
+                       }\r
+                       if (!isdigit(*cp) && *cp != '.') \r
+                               break;\r
+               }\r
+       if ((isxdigit(name[0]) && strchr(name, ':') != NULL) ||\r
+           name[0] == ':')\r
+               for (cp = name;; ++cp) {\r
+                       if (!*cp) {\r
+                               if (*--cp == '.')\r
+                                       break;\r
+                               /*\r
+                                * All-IPv6-legal, no dot at the end.\r
+                                * Fake up a hostent as if we'd actually\r
+                                * done a lookup.\r
+                                */\r
+                               if (inet_pton(af, name, host_addr) <= 0) {\r
+                                       h_errno = HOST_NOT_FOUND;\r
+                                       return (NULL);\r
+                               }\r
+                               strncpy(hostbuf, name, MAXDNAME);\r
+                               hostbuf[MAXDNAME] = '\0';\r
+                               bp = hostbuf + MAXDNAME;\r
+                               len = sizeof hostbuf - MAXDNAME;\r
+                               host.h_name = hostbuf;\r
+                               host.h_aliases = host_aliases;\r
+                               host_aliases[0] = NULL;\r
+                               h_addr_ptrs[0] = (char *)host_addr;\r
+                               h_addr_ptrs[1] = NULL;\r
+                               host.h_addr_list = h_addr_ptrs;\r
+                               h_errno = NETDB_SUCCESS;\r
+                               return (&host);\r
+                       }\r
+                       if (!isxdigit(*cp) && *cp != ':' && *cp != '.') \r
+                               break;\r
+               }\r
+\r
+       if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {\r
+               dprintf("res_search failed (%d)\n", n);\r
+               return (NULL);\r
+       }\r
+       return (gethostanswer(&buf, n, name, type));\r
+}\r
+\r
+struct hostent *\r
+_gethostbydnsaddr(const char *addr, int len, int af)\r
+{\r
+       const u_char *uaddr = (const u_char *)addr;\r
+       static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };\r
+       static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };\r
+       int n, size;\r
+       querybuf buf;\r
+       register struct hostent *hp;\r
+       char qbuf[MAXDNAME+1], *qp;\r
+#ifdef SUNSECURITY\r
+       register struct hostent *rhp;\r
+       char **haddr;\r
+       u_long old_options;\r
+       char hname2[MAXDNAME+1];\r
+#endif /*SUNSECURITY*/\r
+       \r
+       if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+               h_errno = NETDB_INTERNAL;\r
+               return (NULL);\r
+       }\r
+       if (af == AF_INET6 && len == IN6ADDRSZ &&\r
+           (!bcmp(uaddr, mapped, sizeof mapped) ||\r
+            !bcmp(uaddr, tunnelled, sizeof tunnelled))) {\r
+               /* Unmap. */\r
+               addr += sizeof mapped;\r
+               uaddr += sizeof mapped;\r
+               af = AF_INET;\r
+               len = INADDRSZ;\r
+       }\r
+       switch (af) {\r
+       case AF_INET:\r
+               size = INADDRSZ;\r
+               break;\r
+       case AF_INET6:\r
+               size = IN6ADDRSZ;\r
+               break;\r
+       default:\r
+               errno = EAFNOSUPPORT;\r
+               h_errno = NETDB_INTERNAL;\r
+               return (NULL);\r
+       }\r
+       if (size != len) {\r
+               errno = EINVAL;\r
+               h_errno = NETDB_INTERNAL;\r
+               return (NULL);\r
+       }\r
+       switch (af) {\r
+       case AF_INET:\r
+               (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",\r
+                              (uaddr[3] & 0xff),\r
+                              (uaddr[2] & 0xff),\r
+                              (uaddr[1] & 0xff),\r
+                              (uaddr[0] & 0xff));\r
+               break;\r
+       case AF_INET6:\r
+               qp = qbuf;\r
+               for (n = IN6ADDRSZ - 1; n >= 0; n--) {\r
+                       qp += SPRINTF((qp, "%x.%x.",\r
+                                      uaddr[n] & 0xf,\r
+                                      (uaddr[n] >> 4) & 0xf));\r
+               }\r
+               strcpy(qp, "ip6.int");\r
+               break;\r
+       default:\r
+               abort();\r
+       }\r
+       n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);\r
+       if (n < 0) {\r
+               dprintf("res_query failed (%d)\n", n);\r
+               return (NULL);\r
+       }\r
+       if ( NULL == (hp = gethostanswer(&buf, n, qbuf, T_PTR)))\r
+               return (NULL);  /* h_errno was set by gethostanswer() */\r
+#ifdef SUNSECURITY\r
+       if (af == AF_INET) {\r
+           /*\r
+            * turn off search as the name should be absolute,\r
+            * 'localhost' should be matched by defnames\r
+            */\r
+           strncpy(hname2, hp->h_name, MAXDNAME);\r
+           hname2[MAXDNAME] = '\0';\r
+           old_options = _res.options;\r
+           _res.options &= ~RES_DNSRCH;\r
+           _res.options |= RES_DEFNAMES;\r
+           if (!(rhp = gethostbyname(hname2))) {\r
+#ifdef _ORG_FREEBSD_\r
+               syslog(LOG_NOTICE|LOG_AUTH,\r
+                      "gethostbyaddr: No A record for %s (verifying [%s])",\r
+                      hname2, inet_ntoa(*((struct in_addr *)addr)));\r
+#endif\r
+               _res.options = old_options;\r
+               h_errno = HOST_NOT_FOUND;\r
+               return (NULL);\r
+           }\r
+           _res.options = old_options;\r
+           for (haddr = rhp->h_addr_list; *haddr; haddr++)\r
+               if (!memcmp(*haddr, addr, INADDRSZ))\r
+                       break;\r
+           if (!*haddr) {\r
+#ifdef _ORG_FREEBSD_\r
+               syslog(LOG_NOTICE|LOG_AUTH,\r
+                      "gethostbyaddr: A record of %s != PTR record [%s]",\r
+                      hname2, inet_ntoa(*((struct in_addr *)addr)));\r
+#endif\r
+               h_errno = HOST_NOT_FOUND;\r
+               return (NULL);\r
+           }\r
+       }\r
+#endif /*SUNSECURITY*/\r
+       hp->h_addrtype = af;\r
+       hp->h_length = len;\r
+       bcopy(addr, host_addr, len);\r
+       h_addr_ptrs[0] = (char *)host_addr;\r
+       h_addr_ptrs[1] = NULL;\r
+       if (af == AF_INET && (_res.options & RES_USE_INET6)) {\r
+               _map_v4v6_address((char*)host_addr, (char*)host_addr);\r
+               hp->h_addrtype = AF_INET6;\r
+               hp->h_length = IN6ADDRSZ;\r
+       }\r
+       h_errno = NETDB_SUCCESS;\r
+       return (hp);\r
+}\r
+\r
+#ifdef RESOLVSORT\r
+static void\r
+addrsort(char **ap, int num)\r
+{\r
+       short i, j;\r
+       char **p;\r
+       short aval[MAXADDRS];\r
+       short needsort = 0;\r
+\r
+       p = ap;\r
+       for (i = 0; i < num; i++, p++) {\r
+           for (j = 0 ; (unsigned)j < _res.nsort; j++)\r
+               if (_res.sort_list[j].addr.s_addr == \r
+                   (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))\r
+                       break;\r
+           aval[i] = j;\r
+           if (needsort == 0 && i > 0 && j < aval[i-1])\r
+               needsort = i;\r
+       }\r
+       if (!needsort)\r
+           return;\r
+\r
+       while (needsort < num) {\r
+           for (j = needsort - 1; j >= 0; j--) {\r
+               if (aval[j] > aval[j+1]) {\r
+                   char *hp;\r
+\r
+                   i = aval[j];\r
+                   aval[j] = aval[j+1];\r
+                   aval[j+1] = i;\r
+\r
+                   hp = ap[j];\r
+                   ap[j] = ap[j+1];\r
+                   ap[j+1] = hp;\r
+\r
+               } else\r
+                   break;\r
+           }\r
+           needsort++;\r
+       }\r
+}\r
+#endif\r
+void\r
+_sethostdnsent(int stayopen)\r
+{\r
+       if ((_res.options & RES_INIT) == 0 && res_init() == -1)\r
+               return;\r
+       if (stayopen)\r
+               _res.options |= RES_STAYOPEN | RES_USEVC;\r
+}\r
+\r
+void\r
+_endhostdnsent()\r
+{\r
+       _res.options &= ~(RES_STAYOPEN | RES_USEVC);\r
+       res_close();\r
+}\r
diff --git a/StdLib/BsdSocketLib/gethostbyht.c b/StdLib/BsdSocketLib/gethostbyht.c
new file mode 100644 (file)
index 0000000..ac31f8c
--- /dev/null
@@ -0,0 +1,207 @@
+/*-\r
+ * Copyright (c) 1985, 1988, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ * \r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ * -\r
+ * --Copyright--\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)gethostnamadr.c    8.1 (Berkeley) 6/4/93";\r
+static char rcsid[] = "$Id: gethostbyht.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <string.h>\r
+#include <arpa/nameser.h>      /* XXX */\r
+#include <resolv.h>            /* XXX */\r
+#include "Socklib_internals.h"\r
+\r
+#define        MAXALIASES      35\r
+\r
+static struct hostent host;\r
+static char *host_aliases[MAXALIASES];\r
+static char hostbuf[BUFSIZ+1];\r
+static FILE *hostf = NULL;\r
+static u_char host_addr[16];   /* IPv4 or IPv6 */\r
+static char *h_addr_ptrs[2];\r
+static int stayopen = 0;\r
+\r
+void\r
+_sethosthtent(int f)\r
+{\r
+       if (!hostf)\r
+               hostf = fopen(_PATH_HOSTS, "r" );\r
+       else\r
+               rewind(hostf);\r
+       stayopen = f;\r
+}\r
+\r
+void\r
+_endhosthtent()\r
+{\r
+       if (hostf && !stayopen) {\r
+               (void) fclose(hostf);\r
+               hostf = NULL;\r
+       }\r
+}\r
+\r
+struct hostent *\r
+gethostent()\r
+{\r
+       char *p;\r
+       register char *cp, **q;\r
+       int af, len;\r
+\r
+       if (!hostf && ( NULL == (hostf = fopen(_PATH_HOSTS, "r" )))) {\r
+               h_errno = NETDB_INTERNAL;\r
+               return (NULL);\r
+       }\r
+ again:\r
+       if ( NULL == (p = fgets(hostbuf, sizeof hostbuf, hostf))) {\r
+               h_errno = HOST_NOT_FOUND;\r
+               return (NULL);\r
+       }\r
+       if (*p == '#')\r
+               goto again;\r
+       if ( NULL == (cp = strpbrk(p, "#\n")))\r
+               goto again;\r
+       *cp = '\0';\r
+       if ( NULL == (cp = strpbrk(p, " \t")))\r
+               goto again;\r
+       *cp++ = '\0';\r
+       if (inet_pton(AF_INET6, p, host_addr) > 0) {\r
+               af = AF_INET6;\r
+               len = IN6ADDRSZ;\r
+       } else if (inet_pton(AF_INET, p, host_addr) > 0) {\r
+               if (_res.options & RES_USE_INET6) {\r
+                       _map_v4v6_address((char*)host_addr, (char*)host_addr);\r
+                       af = AF_INET6;\r
+                       len = IN6ADDRSZ;\r
+               } else {\r
+                       af = AF_INET;\r
+                       len = INADDRSZ;\r
+               }\r
+       } else {\r
+               goto again;\r
+       }\r
+       h_addr_ptrs[0] = (char *)host_addr;\r
+       h_addr_ptrs[1] = NULL;\r
+       host.h_addr_list = h_addr_ptrs;\r
+       host.h_length = len;\r
+       host.h_addrtype = af;\r
+       while (*cp == ' ' || *cp == '\t')\r
+               cp++;\r
+       host.h_name = cp;\r
+       q = host.h_aliases = host_aliases;\r
+       if ((cp = strpbrk(cp, " \t\r")) != NULL)\r
+               *cp++ = '\0';\r
+       while (cp && *cp) {\r
+               if (*cp == ' ' || *cp == '\t') {\r
+                       cp++;\r
+                       continue;\r
+               }\r
+               if (q < &host_aliases[MAXALIASES - 1])\r
+                       *q++ = cp;\r
+               if ((cp = strpbrk(cp, " \t\r")) != NULL)\r
+                       *cp++ = '\0';\r
+       }\r
+       *q = NULL;\r
+       h_errno = NETDB_SUCCESS;\r
+       return (&host);\r
+}\r
+\r
+struct hostent *\r
+_gethostbyhtname(const char *name, int af)\r
+{\r
+       register struct hostent *p;\r
+       register char **cp;\r
+       \r
+       sethostent(0);\r
+       while ((p = gethostent()) != NULL) {\r
+               if (p->h_addrtype != af)\r
+                       continue;\r
+               if (strcasecmp(p->h_name, name) == 0)\r
+                       break;\r
+               for (cp = p->h_aliases; *cp != 0; cp++)\r
+                       if (strcasecmp(*cp, name) == 0)\r
+                               goto found;\r
+       }\r
+found:\r
+       endhostent();\r
+       return (p);\r
+}\r
+\r
+struct hostent *\r
+_gethostbyhtaddr(const char *addr, int len, int af)\r
+{\r
+       register struct hostent *p;\r
+\r
+       sethostent(0);\r
+       while ((p = gethostent()) != NULL)\r
+               if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))\r
+                       break;\r
+       endhostent();\r
+       return (p);\r
+}\r
diff --git a/StdLib/BsdSocketLib/gethostbynis.c b/StdLib/BsdSocketLib/gethostbynis.c
new file mode 100644 (file)
index 0000000..72081dc
--- /dev/null
@@ -0,0 +1,134 @@
+/*-\r
+ * Copyright (c) 1994, Garrett Wollman\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)$Id: gethostbynis.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";\r
+static char rcsid[] = "$Id: gethostbynis.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <string.h>\r
+#ifdef YP\r
+#include <rpc/rpc.h>\r
+#include <rpcsvc/yp_prot.h>\r
+#include <rpcsvc/ypclnt.h>\r
+#endif\r
+\r
+#define        MAXALIASES      35\r
+#define        MAXADDRS        35\r
+\r
+#ifdef YP\r
+static char *host_aliases[MAXALIASES];\r
+static char hostaddr[MAXADDRS];\r
+static char *host_addrs[2];\r
+#endif /* YP */\r
+\r
+static struct hostent *\r
+_gethostbynis(const char *name, char *map, int af)\r
+{\r
+#ifdef YP\r
+       register char *cp, **q;\r
+       char *result;\r
+       int resultlen;\r
+       static struct hostent h;\r
+       static char *domain = (char *)NULL;\r
+       static char ypbuf[YPMAXRECORD + 2];\r
+\r
+       switch(af) {\r
+       case AF_INET:\r
+               break;\r
+       default:\r
+       case AF_INET6:\r
+               errno = EAFNOSUPPORT;\r
+               return NULL;\r
+       }\r
+\r
+       if (domain == (char *)NULL)\r
+               if (yp_get_default_domain (&domain))\r
+                       return ((struct hostent *)NULL);\r
+\r
+       if (yp_match(domain, map, name, strlen(name), &result, &resultlen))\r
+               return ((struct hostent *)NULL);\r
+\r
+       /* avoid potential memory leak */\r
+       bcopy((char *)result, (char *)&ypbuf, resultlen);\r
+       ypbuf[resultlen] = '\0';\r
+       free(result);\r
+       result = (char *)&ypbuf;\r
+\r
+       if ((cp = index(result, '\n')))\r
+               *cp = '\0';\r
+\r
+       cp = strpbrk(result, " \t");\r
+       *cp++ = '\0';\r
+       h.h_addr_list = host_addrs;\r
+       h.h_addr = hostaddr;\r
+       *((u_long *)h.h_addr) = inet_addr(result);\r
+       h.h_length = sizeof(u_long);\r
+       h.h_addrtype = AF_INET;\r
+       while (*cp == ' ' || *cp == '\t')\r
+               cp++;\r
+       h.h_name = cp;\r
+       q = h.h_aliases = host_aliases;\r
+       cp = strpbrk(cp, " \t");\r
+       if (cp != NULL)\r
+               *cp++ = '\0';\r
+       while (cp && *cp) {\r
+               if (*cp == ' ' || *cp == '\t') {\r
+                       cp++;\r
+                       continue;\r
+               }\r
+               if (q < &host_aliases[MAXALIASES - 1])\r
+                       *q++ = cp;\r
+               cp = strpbrk(cp, " \t");\r
+               if (cp != NULL)\r
+                       *cp++ = '\0';\r
+       }\r
+       *q = NULL;\r
+       return (&h);\r
+#else\r
+       return (NULL);\r
+#endif /* YP */\r
+}\r
+\r
+struct hostent *\r
+_gethostbynisname(const char *name, int af)\r
+{\r
+       return _gethostbynis(name, "hosts.byname", af);\r
+}\r
+\r
+struct hostent *\r
+_gethostbynisaddr(const char *addr, int len, int af)\r
+{\r
+       return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af);\r
+}\r
diff --git a/StdLib/BsdSocketLib/gethostnamadr.c b/StdLib/BsdSocketLib/gethostnamadr.c
new file mode 100644 (file)
index 0000000..74a9ea1
--- /dev/null
@@ -0,0 +1,225 @@
+/*-\r
+ * Copyright (c) 1994, Garrett Wollman\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)$Id: gethostnamadr.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";\r
+static char rcsid[] = "$Id: gethostnamadr.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <paths.h>\r
+#include <string.h>\r
+#include <arpa/nameser.h>              /* XXX hack for _res */\r
+#include <resolv.h>                    /* XXX hack for _res */\r
+\r
+#include "Socklib_internals.h"\r
+\r
+\r
+enum service_type {\r
+  SERVICE_NONE = 0,\r
+  SERVICE_BIND,\r
+  SERVICE_HOSTS,\r
+  SERVICE_NIS };\r
+#define SERVICE_MAX    SERVICE_NIS\r
+\r
+static struct {\r
+  const char *name;\r
+  enum service_type type;\r
+} service_names[] = {\r
+  { "hosts", SERVICE_HOSTS },\r
+  { _PATH_HOSTS, SERVICE_HOSTS },\r
+  { "hosttable", SERVICE_HOSTS },\r
+  { "htable", SERVICE_HOSTS },\r
+  { "bind", SERVICE_BIND },\r
+  { "dns", SERVICE_BIND },\r
+  { "domain", SERVICE_BIND },\r
+  { "yp", SERVICE_NIS },\r
+  { "yellowpages", SERVICE_NIS },\r
+  { "nis", SERVICE_NIS },\r
+  { 0, SERVICE_NONE }\r
+};\r
+\r
+static enum service_type service_order[SERVICE_MAX + 1];\r
+static int service_done = 0;\r
+\r
+static enum service_type\r
+get_service_name(const char *name) {\r
+       int i;\r
+       for(i = 0; service_names[i].type != SERVICE_NONE; i++) {\r
+               if(!strcasecmp(name, service_names[i].name)) {\r
+                       return service_names[i].type;\r
+               }\r
+       }\r
+       return SERVICE_NONE;\r
+}\r
+\r
+static void\r
+init_services()\r
+{\r
+       char *cp, *p, buf[BUFSIZ];\r
+       register int cc = 0;\r
+       FILE *fd;\r
+\r
+       if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) {\r
+                               /* make some assumptions */\r
+               service_order[0] = SERVICE_HOSTS;\r
+               service_order[1] = SERVICE_BIND;\r
+               service_order[2] = SERVICE_NONE;\r
+       } else {\r
+               while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {\r
+                       if(buf[0] == '#')\r
+                               continue;\r
+\r
+                       p = buf;\r
+                       while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')\r
+                               ;\r
+                       if (cp == NULL)\r
+                               continue;\r
+                       do {\r
+                               if (isalpha(cp[0])) {\r
+                                       service_order[cc] = get_service_name(cp);\r
+                                       if(service_order[cc] != SERVICE_NONE)\r
+                                               cc++;\r
+                               }\r
+                               while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')\r
+                                       ;\r
+                       } while(cp != NULL && cc < SERVICE_MAX);\r
+               }\r
+               service_order[cc] = SERVICE_NONE;\r
+               fclose(fd);\r
+       }\r
+       service_done = 1;\r
+}\r
+\r
+struct hostent *\r
+gethostbyname(const char *name)\r
+{\r
+       struct hostent *hp;\r
+\r
+       if (_res.options & RES_USE_INET6) {             /* XXX */\r
+               hp = gethostbyname2(name, AF_INET6);    /* XXX */\r
+               if (hp)                                 /* XXX */\r
+                       return (hp);                    /* XXX */\r
+       }                                               /* XXX */\r
+       return (gethostbyname2(name, AF_INET));\r
+}\r
+\r
+struct hostent *\r
+gethostbyname2(const char *name, int type)\r
+{\r
+       struct hostent *hp = 0;\r
+       int nserv = 0;\r
+\r
+       if (!service_done)\r
+               init_services();\r
+\r
+       while (!hp) {\r
+               switch (service_order[nserv]) {\r
+                     case SERVICE_NONE:\r
+                       return NULL;\r
+                     case SERVICE_HOSTS:\r
+                       hp = _gethostbyhtname(name, type);\r
+                       break;\r
+                     case SERVICE_BIND:\r
+                       hp = _gethostbydnsname(name, type);\r
+                       break;\r
+                     case SERVICE_NIS:\r
+                       hp = _gethostbynisname(name, type);\r
+                       break;\r
+               }\r
+               nserv++;\r
+       }\r
+       return hp;\r
+}\r
+\r
+struct hostent *\r
+gethostbyaddr(const char *addr, socklen_t len, int type)\r
+{\r
+       struct hostent *hp = 0;\r
+       int nserv = 0;\r
+\r
+       if (!service_done)\r
+               init_services();\r
+\r
+       while (!hp) {\r
+               switch (service_order[nserv]) {\r
+                     case SERVICE_NONE:\r
+                       return 0;\r
+                     case SERVICE_HOSTS:\r
+                       hp = _gethostbyhtaddr(addr, len, type);\r
+                       break;\r
+                     case SERVICE_BIND:\r
+                       hp = _gethostbydnsaddr(addr, len, type);\r
+                       break;\r
+                     case SERVICE_NIS:\r
+                       hp = _gethostbynisaddr(addr, len, type);\r
+                       break;\r
+               }\r
+               nserv++;\r
+       }\r
+       return hp;\r
+}\r
+\r
+#ifdef _THREAD_SAFE\r
+struct hostent_data;\r
+\r
+/*\r
+ * Temporary function (not thread safe)\r
+ */\r
+int gethostbyaddr_r(const char *addr, int len, int type,\r
+       struct hostent *result, struct hostent_data *buffer)\r
+{\r
+       struct hostent *hp;\r
+       int ret;\r
+       if ((hp = gethostbyaddr(addr, len, type)) == NULL) {\r
+               ret = -1;\r
+       } else {\r
+               memcpy(result, hp, sizeof(struct hostent));\r
+               ret = 0;\r
+       }\r
+       return(ret);\r
+}\r
+#endif\r
+\r
+void\r
+sethostent(int stayopen)\r
+{\r
+       _sethosthtent(stayopen);\r
+       _sethostdnsent(stayopen);\r
+}\r
+\r
+void\r
+endhostent()\r
+{\r
+       _endhosthtent();\r
+       _endhostdnsent();\r
+}\r
diff --git a/StdLib/BsdSocketLib/gethostname.c b/StdLib/BsdSocketLib/gethostname.c
new file mode 100644 (file)
index 0000000..1b0742a
--- /dev/null
@@ -0,0 +1,92 @@
+/*\r
+ * Copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software must\r
+ *    display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and its\r
+ *    contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be used to\r
+ *    endorse or promote products derived from this software without specific\r
+ *    prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR\r
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+\r
+/*++\r
+\r
+Module Name:\r
+\r
+    gethostname.c\r
+    \r
+Abstract:\r
+\r
+    Map FreeBSD gethostname call to EFI Interface\r
+\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+int\r
+gethostname(\r
+       char    *name,\r
+       size_t          namelen\r
+       )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Get the hostname for this system.\r
+\r
+Arguments:\r
+    \r
+       name            - Pointer to storage for hostname.\r
+       namelen         - Length of name\r
+\r
+Returns:\r
+\r
+       0 on success, -1 if not set\r
+\r
+--*/\r
+{\r
+       char    *pHost;\r
+\r
+       pHost = getenv ("HOSTNAME");\r
+\r
+       if ( pHost == NULL ) {\r
+               *name = 0;\r
+       } else {\r
+               strncpy (name, pHost, namelen);\r
+               name[namelen-1] = 0;\r
+       }\r
+\r
+       return (0);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getnetbydns.c b/StdLib/BsdSocketLib/getnetbydns.c
new file mode 100644 (file)
index 0000000..b0fdef5
--- /dev/null
@@ -0,0 +1,318 @@
+/*-\r
+ * Copyright (c) 1985, 1988, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ * \r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * -\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ * -\r
+ * --Copyright--\r
+ */\r
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro\r
+ *     Dep. Matematica Universidade de Coimbra, Portugal, Europe\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)gethostnamadr.c    8.1 (Berkeley) 6/4/93";\r
+static char rcsid[] = "$Id: getnetbydns.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+\r
+#include <stdio.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#ifdef _ORG_FREEBSD_\r
+#include <syslog.h>\r
+#endif\r
+\r
+#include "res_config.h"\r
+#include "Socklib_internals.h"\r
+\r
+extern int h_errno;\r
+\r
+#define BYADDR 0\r
+#define BYNAME 1\r
+#define        MAXALIASES      35\r
+\r
+#if PACKETSZ > 1024\r
+#define        MAXPACKET       PACKETSZ\r
+#else\r
+#define        MAXPACKET       1024\r
+#endif\r
+\r
+typedef union {\r
+       HEADER  hdr;\r
+       u_char  buf[MAXPACKET];\r
+} querybuf;\r
+\r
+typedef union {\r
+       long    al;\r
+       char    ac;\r
+} align;\r
+\r
+static struct netent *\r
+getnetanswer(querybuf *answer, int anslen, int net_i)\r
+{\r
+\r
+       register HEADER *hp;\r
+       register u_char *cp;\r
+       register int n;\r
+       u_char *eom;\r
+       int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;\r
+       char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];\r
+       char *in, *st, *pauxt, *bp, **ap;\r
+       char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;\r
+static struct netent net_entry;\r
+static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];\r
+\r
+       /*\r
+        * find first satisfactory answer\r
+        *\r
+        *      answer --> +------------+  ( MESSAGE )\r
+        *                 |   Header   |\r
+        *                 +------------+\r
+        *                 |  Question  | the question for the name server\r
+        *                 +------------+\r
+        *                 |   Answer   | RRs answering the question\r
+        *                 +------------+\r
+        *                 | Authority  | RRs pointing toward an authority\r
+        *                 | Additional | RRs holding additional information\r
+        *                 +------------+\r
+        */\r
+       eom = answer->buf + anslen;\r
+       hp = &answer->hdr;\r
+       ancount = ntohs(hp->ancount); /* #/records in the answer section */\r
+       qdcount = ntohs(hp->qdcount); /* #/entries in the question section */\r
+       bp = netbuf;\r
+       buflen = sizeof(netbuf);\r
+       cp = answer->buf + HFIXEDSZ;\r
+       if (!qdcount) {\r
+               if (hp->aa)\r
+                       h_errno = HOST_NOT_FOUND;\r
+               else\r
+                       h_errno = TRY_AGAIN;\r
+               return (NULL);\r
+       }\r
+       while (qdcount-- > 0)\r
+               cp += __dn_skipname(cp, eom) + QFIXEDSZ;\r
+       ap = net_aliases;\r
+       *ap = NULL;\r
+       net_entry.n_aliases = net_aliases;\r
+       haveanswer = 0;\r
+       while (--ancount >= 0 && cp < eom) {\r
+               n = dn_expand(answer->buf, eom, cp, bp, buflen);\r
+               if ((n < 0) || !res_dnok(bp))\r
+                       break;\r
+               cp += n;\r
+               ans[0] = '\0';\r
+               (void)strncpy(&ans[0], bp, sizeof(ans) - 1);\r
+               ans[sizeof(ans) - 1] = '\0';\r
+               GETSHORT(type, cp);\r
+               GETSHORT(class, cp);\r
+               cp += INT32SZ;          /* TTL */\r
+               GETSHORT(n, cp);\r
+               if (class == C_IN && type == T_PTR) {\r
+                       n = dn_expand(answer->buf, eom, cp, bp, buflen);\r
+                       if ((n < 0) || !res_hnok(bp)) {\r
+                               cp += n;\r
+                               return (NULL);\r
+                       }\r
+                       cp += n; \r
+                       *ap++ = bp;\r
+                       bp += strlen(bp) + 1;\r
+                       net_entry.n_addrtype =\r
+                               (class == C_IN) ? AF_INET : AF_UNSPEC;\r
+                       haveanswer++;\r
+               }\r
+       }\r
+       if (haveanswer) {\r
+               *ap = NULL;\r
+               switch (net_i) {\r
+               case BYADDR:\r
+                       net_entry.n_name = *net_entry.n_aliases;\r
+                       net_entry.n_net = 0L;\r
+                       break;\r
+               case BYNAME:\r
+                       in = *net_entry.n_aliases;\r
+                       net_entry.n_name = &ans[0];\r
+                       aux2[0] = '\0';\r
+                       for (i = 0; i < 4; i++) {\r
+                               for (st = in, nchar = 0;\r
+                                    *st != '.';\r
+                                    st++, nchar++)\r
+                                       ;\r
+                               if (nchar != 1 || *in != '0' || flag) {\r
+                                       flag = 1;\r
+                                       (void)strncpy(paux1,\r
+                                                     (i==0) ? in : in-1,\r
+                                                     (i==0) ?nchar : nchar+1);\r
+                                       paux1[(i==0) ? nchar : nchar+1] = '\0';\r
+                                       pauxt = paux2;\r
+                                       paux2 = strcat(paux1, paux2);\r
+                                       paux1 = pauxt;\r
+                               }\r
+                               in = ++st;\r
+                       }                 \r
+                       net_entry.n_net = inet_network(paux2);\r
+                       break;\r
+               }\r
+               net_entry.n_aliases++;\r
+               return (&net_entry);\r
+       }\r
+       h_errno = TRY_AGAIN;\r
+       return (NULL);\r
+}\r
+\r
+struct netent *\r
+_getnetbydnsaddr(register unsigned long net, register int net_type)\r
+{\r
+       unsigned int netbr[4];\r
+       int nn, anslen;\r
+       querybuf buf;\r
+       char qbuf[MAXDNAME];\r
+       unsigned long net2;\r
+       struct netent *net_entry;\r
+\r
+       if (net_type != AF_INET)\r
+               return (NULL);\r
+\r
+       for (nn = 4, net2 = net; net2; net2 >>= 8)\r
+               netbr[--nn] = net2 & 0xff;\r
+       switch (nn) {\r
+       case 3:         /* Class A */\r
+               sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);\r
+               break;\r
+       case 2:         /* Class B */\r
+               sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);\r
+               break;\r
+       case 1:         /* Class C */\r
+               sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],\r
+                   netbr[1]);\r
+               break;\r
+       case 0:         /* Class D - E */\r
+               sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],\r
+                   netbr[1], netbr[0]);\r
+               break;\r
+       }\r
+       anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));\r
+       if (anslen < 0) {\r
+#ifdef DEBUG\r
+               if (_res.options & RES_DEBUG)\r
+                       printf("res_query failed\n");\r
+#endif\r
+               return (NULL);\r
+       }\r
+       net_entry = getnetanswer(&buf, anslen, BYADDR);\r
+       if (net_entry) {\r
+               unsigned u_net = net;   /* maybe net should be unsigned ? */\r
+\r
+               /* Strip trailing zeros */\r
+               while ((u_net & 0xff) == 0 && u_net != 0)\r
+                       u_net >>= 8;\r
+               net_entry->n_net = u_net;\r
+               return (net_entry);\r
+       }\r
+       return (NULL);\r
+}\r
+\r
+struct netent *\r
+_getnetbydnsname(register const char *net)\r
+{\r
+       int anslen;\r
+       querybuf buf;\r
+       char qbuf[MAXDNAME];\r
+\r
+       if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+               h_errno = NETDB_INTERNAL;\r
+               return (NULL);\r
+       }\r
+       strncpy(qbuf, net, sizeof(qbuf) - 1);\r
+       qbuf[sizeof(qbuf) - 1] = '\0';\r
+       anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));\r
+       if (anslen < 0) {\r
+#ifdef DEBUG\r
+               if (_res.options & RES_DEBUG)\r
+                       printf("res_query failed\n");\r
+#endif\r
+               return (NULL);\r
+       }\r
+       return getnetanswer(&buf, anslen, BYNAME);\r
+}\r
+\r
+void\r
+_setnetdnsent(int stayopen)\r
+{\r
+       if (stayopen)\r
+               _res.options |= RES_STAYOPEN | RES_USEVC;\r
+}\r
+\r
+void\r
+_endnetdnsent()\r
+{\r
+       _res.options &= ~(RES_STAYOPEN | RES_USEVC);\r
+       res_close();\r
+}\r
diff --git a/StdLib/BsdSocketLib/getnetbyht.c b/StdLib/BsdSocketLib/getnetbyht.c
new file mode 100644 (file)
index 0000000..08b8042
--- /dev/null
@@ -0,0 +1,169 @@
+/*\r
+ * Copyright (c) 1983, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro\r
+ *     Dep. Matematica Universidade de Coimbra, Portugal, Europe\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * from getnetent.c    1.1 (Coimbra) 93/06/02\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)getnetent.c        8.1 (Berkeley) 6/4/93";\r
+static char orig_rcsid[] = "From: Id: getnetent.c,v 8.4 1997/06/01 20:34:37 vixie Exp";\r
+static chat rcsid[] = "$Id: getnetbyht.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#define        MAXALIASES      35\r
+\r
+static FILE *netf;\r
+static char line[BUFSIZ+1];\r
+static struct netent net;\r
+static char *net_aliases[MAXALIASES];\r
+static int _net_stayopen;\r
+\r
+void\r
+_setnethtent(int f)\r
+{\r
+\r
+       if (netf == NULL)\r
+               netf = fopen(_PATH_NETWORKS, "r" );\r
+       else\r
+               rewind(netf);\r
+       _net_stayopen |= f;\r
+}\r
+\r
+void\r
+_endnethtent()\r
+{\r
+\r
+       if (netf) {\r
+               fclose(netf);\r
+               netf = NULL;\r
+       }\r
+       _net_stayopen = 0;\r
+}\r
+\r
+struct netent *\r
+getnetent()\r
+{\r
+       char *p;\r
+       register char *cp, **q;\r
+\r
+       if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)\r
+               return (NULL);\r
+again:\r
+       p = fgets(line, sizeof line, netf);\r
+       if (p == NULL)\r
+               return (NULL);\r
+       if (*p == '#')\r
+               goto again;\r
+       cp = strpbrk(p, "#\n");\r
+       if (cp == NULL)\r
+               goto again;\r
+       *cp = '\0';\r
+       net.n_name = p;\r
+       cp = strpbrk(p, " \t");\r
+       if (cp == NULL)\r
+               goto again;\r
+       *cp++ = '\0';\r
+       while (*cp == ' ' || *cp == '\t')\r
+               cp++;\r
+       p = strpbrk(cp, " \t");\r
+       if (p != NULL)\r
+               *p++ = '\0';\r
+       net.n_net = inet_network(cp);\r
+       net.n_addrtype = AF_INET;\r
+       q = net.n_aliases = net_aliases;\r
+       if (p != NULL) \r
+               cp = p;\r
+       while (cp && *cp) {\r
+               if (*cp == ' ' || *cp == '\t') {\r
+                       cp++;\r
+                       continue;\r
+               }\r
+               if (q < &net_aliases[MAXALIASES - 1])\r
+                       *q++ = cp;\r
+               cp = strpbrk(cp, " \t");\r
+               if (cp != NULL)\r
+                       *cp++ = '\0';\r
+       }\r
+       *q = NULL;\r
+       return (&net);\r
+}\r
+\r
+struct netent *\r
+_getnetbyhtname(register const char *name)\r
+{\r
+       register struct netent *p;\r
+       register char **cp;\r
+\r
+       setnetent(_net_stayopen);\r
+       while ( NULL != (p = getnetent()) ) {\r
+               if (strcasecmp(p->n_name, name) == 0)\r
+                       break;\r
+               for (cp = p->n_aliases; *cp != 0; cp++)\r
+                       if (strcasecmp(*cp, name) == 0)\r
+                               goto found;\r
+       }\r
+found:\r
+       if (!_net_stayopen)\r
+               endnetent();\r
+       return (p);\r
+}\r
+\r
+struct netent *\r
+_getnetbyhtaddr(register unsigned long net, register int type)\r
+{\r
+       register struct netent *p;\r
+\r
+       setnetent(_net_stayopen);\r
+       while ( NULL != (p = getnetent()) )\r
+               if (p->n_addrtype == type && p->n_net == net)\r
+                       break;\r
+       if (!_net_stayopen)\r
+               endnetent();\r
+       return (p);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getnetbynis.c b/StdLib/BsdSocketLib/getnetbynis.c
new file mode 100644 (file)
index 0000000..f81ca03
--- /dev/null
@@ -0,0 +1,171 @@
+/*-\r
+ * Copyright (c) 1994, Garrett Wollman\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)$Id: getnetbynis.c,v 1.1.1.1 2003/11/19 01:51:28 kyu3 Exp $";\r
+static char rcsid[] = "$Id: getnetbynis.c,v 1.1.1.1 2003/11/19 01:51:28 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <string.h>\r
+#include <arpa/nameser.h>\r
+#ifdef YP\r
+#include <rpc/rpc.h>\r
+#include <rpcsvc/yp_prot.h>\r
+#include <rpcsvc/ypclnt.h>\r
+#endif\r
+\r
+#define        MAXALIASES      35\r
+#define        MAXADDRS        35\r
+\r
+#ifdef YP\r
+static char *host_aliases[MAXALIASES];\r
+#endif /* YP */\r
+\r
+static struct netent *\r
+_getnetbynis(const char *name, char *map, int af)\r
+{\r
+#ifdef YP\r
+       register char *cp, **q;\r
+       static char *result;\r
+       int resultlen;\r
+       static struct netent h;\r
+       static char *domain = (char *)NULL;\r
+       static char ypbuf[YPMAXRECORD + 2];\r
+\r
+       switch(af) {\r
+       case AF_INET:\r
+               break;\r
+       default:\r
+       case AF_INET6:\r
+               errno = EAFNOSUPPORT;\r
+               return NULL;\r
+       }\r
+\r
+       if (domain == (char *)NULL)\r
+               if (yp_get_default_domain (&domain))\r
+                       return (NULL);\r
+\r
+       if (yp_match(domain, map, name, strlen(name), &result, &resultlen))\r
+               return (NULL);\r
+\r
+       bcopy((char *)result, (char *)&ypbuf, resultlen);\r
+       ypbuf[resultlen] = '\0';\r
+       free(result);\r
+       result = (char *)&ypbuf;\r
+\r
+       if ((cp = index(result, '\n')))\r
+               *cp = '\0';\r
+\r
+       cp = strpbrk(result, " \t");\r
+       *cp++ = '\0';\r
+       h.n_name = result;\r
+\r
+       while (*cp == ' ' || *cp == '\t')\r
+               cp++;\r
+\r
+       h.n_net = inet_network(cp);\r
+       h.n_addrtype = AF_INET;\r
+\r
+       q = h.n_aliases = host_aliases;\r
+       cp = strpbrk(cp, " \t");\r
+       if (cp != NULL)\r
+               *cp++ = '\0';\r
+       while (cp && *cp) {\r
+               if (*cp == ' ' || *cp == '\t') {\r
+                       cp++;\r
+                       continue;\r
+               }\r
+               if (q < &host_aliases[MAXALIASES - 1])\r
+                       *q++ = cp;\r
+               cp = strpbrk(cp, " \t");\r
+               if (cp != NULL)\r
+                       *cp++ = '\0';\r
+       }\r
+       *q = NULL;\r
+       return (&h);\r
+#else\r
+       return (NULL);\r
+#endif\r
+}\r
+\r
+struct netent *\r
+_getnetbynisname(const char *name)\r
+{\r
+       return _getnetbynis(name, "networks.byname", AF_INET);\r
+}\r
+\r
+struct netent *\r
+_getnetbynisaddr(unsigned long addr, int af)\r
+{\r
+       char *str, *cp;\r
+       unsigned long net2;\r
+       int nn;\r
+       unsigned int netbr[4];\r
+       char buf[MAXDNAME];\r
+\r
+       if (af != AF_INET) {\r
+               errno = EAFNOSUPPORT;\r
+               return (NULL);\r
+       }\r
+\r
+        for (nn = 4, net2 = addr; net2; net2 >>= 8) {\r
+                netbr[--nn] = net2 & 0xff;\r
+       }\r
+\r
+       switch (nn) {\r
+       case 3:         /* Class A */\r
+               sprintf(buf, "%u", netbr[3]);\r
+               break;\r
+        case 2:                /* Class B */\r
+               sprintf(buf, "%u.%u", netbr[2], netbr[3]);\r
+               break;\r
+        case 1:                /* Class C */\r
+               sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]);\r
+                break;\r
+        case 0:                /* Class D - E */\r
+               sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1],\r
+                       netbr[2], netbr[3]);\r
+               break;\r
+       }\r
+\r
+       str = (char *)&buf;\r
+       cp = str + (strlen(str) - 2);\r
+\r
+       while(!strcmp(cp, ".0")) {\r
+               *cp = '\0';\r
+               cp = str + (strlen(str) - 2);\r
+       }\r
+\r
+       return _getnetbynis(str, "networks.byaddr", af);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getnetnamadr.c b/StdLib/BsdSocketLib/getnetnamadr.c
new file mode 100644 (file)
index 0000000..b2eb737
--- /dev/null
@@ -0,0 +1,186 @@
+/*-\r
+ * Copyright (c) 1994, Garrett Wollman\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char rcsid[] = "$Id: getnetnamadr.c,v 1.1.1.1 2003/11/19 01:51:28 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <paths.h>\r
+#include <string.h>\r
+\r
+#include "Socklib_internals.h"\r
+\r
+enum service_type {\r
+  SERVICE_NONE = 0,\r
+  SERVICE_BIND,\r
+  SERVICE_TABLE,\r
+  SERVICE_NIS };\r
+#define SERVICE_MAX    SERVICE_NIS\r
+\r
+static struct {\r
+  const char *name;\r
+  enum service_type type;\r
+} service_names[] = {\r
+  { "hosts", SERVICE_TABLE },\r
+  { _PATH_HOSTS, SERVICE_TABLE },\r
+  { "hosttable", SERVICE_TABLE },\r
+  { "htable", SERVICE_TABLE },\r
+  { "bind", SERVICE_BIND },\r
+  { "dns", SERVICE_BIND },\r
+  { "domain", SERVICE_BIND },\r
+  { "yp", SERVICE_NIS },\r
+  { "yellowpages", SERVICE_NIS },\r
+  { "nis", SERVICE_NIS },\r
+  { 0, SERVICE_NONE }\r
+};\r
+\r
+static enum service_type service_order[SERVICE_MAX + 1];\r
+static int service_done = 0;\r
+\r
+static enum service_type\r
+get_service_name(const char *name) {\r
+       int i;\r
+       for(i = 0; service_names[i].type != SERVICE_NONE; i++) {\r
+               if(!strcasecmp(name, service_names[i].name)) {\r
+                       return service_names[i].type;\r
+               }\r
+       }\r
+       return SERVICE_NONE;\r
+}\r
+\r
+static void\r
+init_services()\r
+{\r
+       char *cp, *p, buf[BUFSIZ];\r
+       register int cc = 0;\r
+       FILE *fd;\r
+\r
+       if ((fd = (FILE *)fopen(_PATH_NETCONF, "r")) == NULL) {\r
+                               /* make some assumptions */\r
+               service_order[0] = SERVICE_TABLE;\r
+               service_order[1] = SERVICE_NONE;\r
+       } else {\r
+               while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {\r
+                       if(buf[0] == '#')\r
+                               continue;\r
+\r
+                       p = buf;\r
+                       while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')\r
+                               ;\r
+                       if (cp == NULL)\r
+                               continue;\r
+                       do {\r
+                               if (isalpha(cp[0])) {\r
+                                       service_order[cc] = get_service_name(cp);\r
+                                       if(service_order[cc] != SERVICE_NONE)\r
+                                               cc++;\r
+                               }\r
+                               while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')\r
+                                       ;\r
+                       } while(cp != NULL && cc < SERVICE_MAX);\r
+               }\r
+               service_order[cc] = SERVICE_NONE;\r
+               fclose(fd);\r
+       }\r
+       service_done = 1;\r
+}\r
+\r
+struct netent *\r
+getnetbyname(const char *name)\r
+{\r
+       struct netent *hp = 0;\r
+       int nserv = 0;\r
+\r
+       if (!service_done)\r
+               init_services();\r
+\r
+       while (!hp) {\r
+               switch (service_order[nserv]) {\r
+                     case SERVICE_NONE:\r
+                       return NULL;\r
+                     case SERVICE_TABLE:\r
+                       hp = _getnetbyhtname(name);\r
+                       break;\r
+                     case SERVICE_BIND:\r
+                       hp = _getnetbydnsname(name);\r
+                       break;\r
+                     case SERVICE_NIS:\r
+                       hp = _getnetbynisname(name);\r
+                       break;\r
+               }\r
+               nserv++;\r
+       }\r
+       return hp;\r
+}\r
+\r
+struct netent *\r
+getnetbyaddr(uint32_t addr, int af)\r
+{\r
+       struct netent *hp = 0;\r
+       int nserv = 0;\r
+\r
+       if (!service_done)\r
+               init_services();\r
+\r
+       while (!hp) {\r
+               switch (service_order[nserv]) {\r
+                     case SERVICE_NONE:\r
+                       return 0;\r
+                     case SERVICE_TABLE:\r
+                       hp = _getnetbyhtaddr(addr, af);\r
+                       break;\r
+                     case SERVICE_BIND:\r
+                       hp = _getnetbydnsaddr(addr, af);\r
+                       break;\r
+                     case SERVICE_NIS:\r
+                       hp = _getnetbynisaddr(addr, af);\r
+                       break;\r
+               }\r
+               nserv++;\r
+       }\r
+       return hp;\r
+}\r
+\r
+void\r
+setnetent(int stayopen)\r
+{\r
+       _setnethtent(stayopen);\r
+       _setnetdnsent(stayopen);\r
+}\r
+\r
+void\r
+endnetent()\r
+{\r
+       _endnethtent();\r
+       _endnetdnsent();\r
+}\r
diff --git a/StdLib/BsdSocketLib/getpeername.c b/StdLib/BsdSocketLib/getpeername.c
new file mode 100644 (file)
index 0000000..850308a
--- /dev/null
@@ -0,0 +1,73 @@
+/** @file\r
+  Implement the getpeername API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Get the remote address\r
+\r
+  The ::getpeername routine retrieves the remote system address from the socket.\r
+  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html#">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [out] address  Network address to receive the remote system address\r
+\r
+  @param [in] address_len Length of the remote network address structure\r
+\r
+  @returns    ::getpeername returns zero (0) if successful or -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+int\r
+getpeername (\r
+  int s,\r
+  struct sockaddr * address,\r
+  socklen_t * address_len\r
+  )\r
+{\r
+  int RetVal;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  RetVal = -1;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Get the remote address\r
+    //\r
+    Status = pSocketProtocol->pfnGetPeer ( pSocketProtocol,\r
+                                           address,\r
+                                           address_len,\r
+                                           &errno );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      RetVal = 0;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return RetVal;\r
+}\r
diff --git a/StdLib/BsdSocketLib/getproto.c b/StdLib/BsdSocketLib/getproto.c
new file mode 100644 (file)
index 0000000..9924d00
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+ * Copyright (c) 1983, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <netdb.h>\r
+\r
+extern int _proto_stayopen;\r
+\r
+struct protoent *\r
+getprotobynumber(register int proto)\r
+{\r
+       register struct protoent *p;\r
+\r
+       setprotoent(_proto_stayopen);\r
+       while ( NULL != (p = getprotoent()) )\r
+               if (p->p_proto == proto)\r
+                       break;\r
+       if (!_proto_stayopen)\r
+               endprotoent();\r
+       return (p);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getprotoent.c b/StdLib/BsdSocketLib/getprotoent.c
new file mode 100644 (file)
index 0000000..3360812
--- /dev/null
@@ -0,0 +1,118 @@
+/*\r
+ * Copyright (c) 1983, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)getprotoent.c      8.1 (Berkeley) 6/4/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#define        MAXALIASES      35\r
+\r
+static FILE *protof = NULL;\r
+static char line[BUFSIZ+1];\r
+static struct protoent proto;\r
+static char *proto_aliases[MAXALIASES];\r
+int _proto_stayopen;\r
+\r
+void\r
+setprotoent(int f)\r
+{\r
+       if (protof == NULL)\r
+               protof = fopen(_PATH_PROTOCOLS, "r" );\r
+       else\r
+               rewind(protof);\r
+       _proto_stayopen |= f;\r
+}\r
+\r
+void\r
+endprotoent()\r
+{\r
+       if (protof) {\r
+               fclose(protof);\r
+               protof = NULL;\r
+       }\r
+       _proto_stayopen = 0;\r
+}\r
+\r
+struct protoent *\r
+getprotoent()\r
+{\r
+       char *p;\r
+       register char *cp, **q;\r
+\r
+       if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)\r
+               return (NULL);\r
+again:\r
+       if ((p = fgets(line, BUFSIZ, protof)) == NULL)\r
+               return (NULL);\r
+       if (*p == '#')\r
+               goto again;\r
+       cp = strpbrk(p, "#\n");\r
+       if (cp == NULL)\r
+               goto again;\r
+       *cp = '\0';\r
+       proto.p_name = p;\r
+       cp = strpbrk(p, " \t");\r
+       if (cp == NULL)\r
+               goto again;\r
+       *cp++ = '\0';\r
+       while (*cp == ' ' || *cp == '\t')\r
+               cp++;\r
+       p = strpbrk(cp, " \t");\r
+       if (p != NULL)\r
+               *p++ = '\0';\r
+       proto.p_proto = atoi(cp);\r
+       q = proto.p_aliases = proto_aliases;\r
+       if (p != NULL) {\r
+               cp = p;\r
+               while (cp && *cp) {\r
+                       if (*cp == ' ' || *cp == '\t') {\r
+                               cp++;\r
+                               continue;\r
+                       }\r
+                       if (q < &proto_aliases[MAXALIASES - 1])\r
+                               *q++ = cp;\r
+                       cp = strpbrk(cp, " \t");\r
+                       if (cp != NULL)\r
+                               *cp++ = '\0';\r
+               }\r
+       }\r
+       *q = NULL;\r
+       return (&proto);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getprotoname.c b/StdLib/BsdSocketLib/getprotoname.c
new file mode 100644 (file)
index 0000000..71b35e6
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * Copyright (c) 1983, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)getprotoname.c     8.1 (Berkeley) 6/4/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <netdb.h>\r
+#include <string.h>\r
+\r
+extern int _proto_stayopen;\r
+\r
+struct protoent *\r
+getprotobyname(register const char *name)\r
+{\r
+       register struct protoent *p;\r
+       register char **cp;\r
+\r
+       setprotoent(_proto_stayopen);\r
+       while ( NULL != (p = getprotoent()) ) {\r
+               if (strcmp(p->p_name, name) == 0)\r
+                       break;\r
+               for (cp = p->p_aliases; *cp != 0; cp++)\r
+                       if (strcmp(*cp, name) == 0)\r
+                               goto found;\r
+       }\r
+found:\r
+       if (!_proto_stayopen)\r
+               endprotoent();\r
+       return (p);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getservbyname.c b/StdLib/BsdSocketLib/getservbyname.c
new file mode 100644 (file)
index 0000000..f17c240
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+ * Copyright (c) 1983, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)getservbyname.c    8.1 (Berkeley) 6/4/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <netdb.h>\r
+#include <string.h>\r
+\r
+extern int _serv_stayopen;\r
+\r
+struct servent *\r
+getservbyname(IN const char *name, IN const char *proto)\r
+{\r
+       register struct servent *p;\r
+       register char **cp;\r
+\r
+#ifdef YP\r
+       extern char *___getservbyname_yp;\r
+       extern char *___getservbyproto_yp;\r
+\r
+       ___getservbyname_yp = (char *)name;\r
+       ___getservbyproto_yp = (char *)proto;\r
+#endif\r
+\r
+       setservent(_serv_stayopen);\r
+       while ( NULL != (p = getservent()) ) {\r
+               if (strcmp(name, p->s_name) == 0)\r
+                       goto gotname;\r
+               for (cp = p->s_aliases; *cp; cp++)\r
+                       if (strcmp(name, *cp) == 0)\r
+                               goto gotname;\r
+               continue;\r
+gotname:\r
+               if (proto == 0 || strcmp(p->s_proto, proto) == 0)\r
+                       break;\r
+       }\r
+       if (!_serv_stayopen)\r
+               endservent();\r
+\r
+#ifdef YP\r
+       ___getservbyname_yp = NULL;\r
+       ___getservbyproto_yp = NULL;\r
+#endif\r
+\r
+       return (p);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getservbyport.c b/StdLib/BsdSocketLib/getservbyport.c
new file mode 100644 (file)
index 0000000..d93d813
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ * Copyright (c) 1983, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)getservbyport.c    8.1 (Berkeley) 6/4/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <netdb.h>\r
+#include <string.h>\r
+\r
+extern int _serv_stayopen;\r
+\r
+struct servent *\r
+getservbyport(int port, const char *proto)\r
+{\r
+       register struct servent *p;\r
+\r
+#ifdef YP\r
+       extern int ___getservbyport_yp;\r
+       extern char *___getservbyproto_yp;\r
+\r
+       ___getservbyport_yp = port;\r
+       ___getservbyproto_yp = (char *)proto;\r
+#endif\r
+\r
+       setservent(_serv_stayopen);\r
+       while ( NULL != (p = getservent()) ) {\r
+               if (p->s_port != port)\r
+                       continue;\r
+               if (proto == 0 || strcmp(p->s_proto, proto) == 0)\r
+                       break;\r
+       }\r
+       if (!_serv_stayopen)\r
+               endservent();\r
+\r
+#ifdef YP\r
+       ___getservbyport_yp = 0;\r
+       ___getservbyproto_yp = NULL;\r
+#endif\r
+\r
+       return (p);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getservent.c b/StdLib/BsdSocketLib/getservent.c
new file mode 100644 (file)
index 0000000..572b597
--- /dev/null
@@ -0,0 +1,277 @@
+/*\r
+ * Copyright (c) 1983, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)getservent.c       8.1 (Berkeley) 6/4/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#ifdef YP\r
+#include <rpc/rpc.h>\r
+#include <rpcsvc/yp_prot.h>\r
+#include <rpcsvc/ypclnt.h>\r
+static int serv_stepping_yp = 0;\r
+extern int _yp_check __P(( char ** ));\r
+#endif\r
+\r
+\r
+#define        MAXALIASES      35\r
+\r
+static FILE *servf = NULL;\r
+static char line[BUFSIZ+1];\r
+static struct servent serv;\r
+static char *serv_aliases[MAXALIASES];\r
+int _serv_stayopen;\r
+\r
+#ifdef YP\r
+char *___getservbyname_yp = NULL;\r
+char *___getservbyproto_yp = NULL;\r
+int ___getservbyport_yp = 0;\r
+static char *yp_domain = NULL;\r
+\r
+static int\r
+_getservbyport_yp(line)\r
+       char *line;\r
+{\r
+       char *result;\r
+       int resultlen;\r
+       char buf[YPMAXRECORD + 2];\r
+       int rv;\r
+\r
+       snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp),\r
+                                               ___getservbyproto_yp);\r
+\r
+       ___getservbyport_yp = 0;\r
+       ___getservbyproto_yp = NULL;\r
+\r
+       if(!yp_domain) {\r
+               if(yp_get_default_domain(&yp_domain))\r
+                       return (0);\r
+       }\r
+\r
+       /*\r
+        * We have to be a little flexible here. Ideally you're supposed\r
+        * to have both a services.byname and a services.byport map, but\r
+        * some systems have only services.byname. FreeBSD cheats a little\r
+        * by putting the services.byport information in the same map as\r
+        * services.byname so that either case will work. We allow for both\r
+        * possibilities here: if there is no services.byport map, we try\r
+        * services.byname instead.\r
+        */\r
+       if ((rv = yp_match(yp_domain, "services.byport", buf, strlen(buf),\r
+                                               &result, &resultlen))) {\r
+               if (rv == YPERR_MAP) {\r
+                       if (yp_match(yp_domain, "services.byname", buf,\r
+                                       strlen(buf), &result, &resultlen))\r
+                       return(0);\r
+               } else\r
+                       return(0);\r
+       }\r
+               \r
+       /* getservent() expects lines terminated with \n -- make it happy */\r
+       snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);\r
+\r
+       free(result);\r
+       return(1);\r
+}\r
+\r
+static int\r
+_getservbyname_yp(line)\r
+       char *line;\r
+{\r
+       char *result;\r
+       int resultlen;\r
+       char buf[YPMAXRECORD + 2];\r
+\r
+       if(!yp_domain) {\r
+               if(yp_get_default_domain(&yp_domain))\r
+                       return (0);\r
+       }\r
+\r
+       snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp,\r
+                                               ___getservbyproto_yp);\r
+\r
+       ___getservbyname_yp = 0;\r
+       ___getservbyproto_yp = NULL;\r
+\r
+       if (yp_match(yp_domain, "services.byname", buf, strlen(buf),\r
+                                               &result, &resultlen)) {\r
+               return(0);\r
+       }\r
+               \r
+       /* getservent() expects lines terminated with \n -- make it happy */\r
+       snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);\r
+\r
+       free(result);\r
+       return(1);\r
+}\r
+\r
+static int\r
+_getservent_yp(line)\r
+       char *line;\r
+{\r
+       static char *key = NULL;\r
+       static int keylen;\r
+       char *lastkey, *result;\r
+       int resultlen;\r
+       int rv;\r
+\r
+       if(!yp_domain) {\r
+               if(yp_get_default_domain(&yp_domain))\r
+                       return (0);\r
+       }\r
+\r
+       if (!serv_stepping_yp) {\r
+               if (key)\r
+                       free(key);\r
+               if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,\r
+                            &result, &resultlen))) {\r
+                       serv_stepping_yp = 0;\r
+                       return(0);\r
+               }\r
+               serv_stepping_yp = 1;\r
+       } else {\r
+               lastkey = key;\r
+               rv = yp_next(yp_domain, "services.byname", key, keylen, &key,\r
+                            &keylen, &result, &resultlen);\r
+               free(lastkey);\r
+               if (rv) {\r
+                       serv_stepping_yp = 0;\r
+                       return (0);\r
+               }\r
+       }\r
+\r
+       /* getservent() expects lines terminated with \n -- make it happy */\r
+       snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);\r
+\r
+       free(result);\r
+\r
+       return(1);\r
+}\r
+#endif\r
+\r
+void\r
+setservent(int f)\r
+{\r
+       if (servf == NULL)\r
+               servf = fopen(_PATH_SERVICES, "r" );\r
+       else\r
+               rewind(servf);\r
+       _serv_stayopen |= f;\r
+}\r
+\r
+void\r
+endservent()\r
+{\r
+       if (servf) {\r
+               fclose(servf);\r
+               servf = NULL;\r
+       }\r
+       _serv_stayopen = 0;\r
+}\r
+\r
+struct servent *\r
+getservent()\r
+{\r
+       char *p;\r
+       register char *cp, **q;\r
+\r
+#ifdef YP\r
+       if (serv_stepping_yp && _getservent_yp(line)) {\r
+               p = (char *)&line;\r
+               goto unpack;\r
+       }\r
+tryagain:\r
+#endif\r
+       if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)\r
+               return (NULL);\r
+again:\r
+       if ((p = fgets(line, BUFSIZ, servf)) == NULL)\r
+               return (NULL);\r
+#ifdef YP\r
+       if (*p == '+' && _yp_check(NULL)) {\r
+               if (___getservbyname_yp != NULL) {\r
+                       if (!_getservbyname_yp(line))\r
+                               goto tryagain;\r
+               } \r
+               else if (___getservbyport_yp != 0) {\r
+                       if (!_getservbyport_yp(line))\r
+                               goto tryagain;\r
+               }\r
+               else if (!_getservent_yp(line))\r
+                       goto tryagain;\r
+       }\r
+unpack:\r
+#endif\r
+       if (*p == '#')\r
+               goto again;\r
+       cp = strpbrk(p, "#\n");\r
+       if (cp == NULL)\r
+               goto again;\r
+       *cp = '\0';\r
+       serv.s_name = p;\r
+       p = strpbrk(p, " \t");\r
+       if (p == NULL)\r
+               goto again;\r
+       *p++ = '\0';\r
+       while (*p == ' ' || *p == '\t')\r
+               p++;\r
+       cp = strpbrk(p, ",/");\r
+       if (cp == NULL)\r
+               goto again;\r
+       *cp++ = '\0';\r
+       serv.s_port = htons((u_short)atoi(p));\r
+       serv.s_proto = cp;\r
+       q = serv.s_aliases = serv_aliases;\r
+       cp = strpbrk(cp, " \t");\r
+       if (cp != NULL)\r
+               *cp++ = '\0';\r
+       while (cp && *cp) {\r
+               if (*cp == ' ' || *cp == '\t') {\r
+                       cp++;\r
+                       continue;\r
+               }\r
+               if (q < &serv_aliases[MAXALIASES - 1])\r
+                       *q++ = cp;\r
+               cp = strpbrk(cp, " \t");\r
+               if (cp != NULL)\r
+                       *cp++ = '\0';\r
+       }\r
+       *q = NULL;\r
+       return (&serv);\r
+}\r
diff --git a/StdLib/BsdSocketLib/getsockname.c b/StdLib/BsdSocketLib/getsockname.c
new file mode 100644 (file)
index 0000000..0b72edc
--- /dev/null
@@ -0,0 +1,73 @@
+/** @file\r
+  Implement the getsockname API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Get the local socket address.\r
+\r
+  The ::getsockname routine retrieves the local system address from the socket.\r
+  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html#">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [out] address  Network address to receive the local system address\r
+\r
+  @param [in] address_len Length of the local network address structure\r
+\r
+  @returns    ::getsockname returns zero (0) if successful or -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+int\r
+getsockname (\r
+  int s,\r
+  struct sockaddr * address,\r
+  socklen_t * address_len\r
+  )\r
+{\r
+  int RetVal;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  RetVal = -1;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Get the local socket address\r
+    //\r
+    Status = pSocketProtocol->pfnGetLocal ( pSocketProtocol,\r
+                                            address,\r
+                                            address_len,\r
+                                            &errno );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      RetVal = 0;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return RetVal;\r
+}\r
diff --git a/StdLib/BsdSocketLib/getsockopt.c b/StdLib/BsdSocketLib/getsockopt.c
new file mode 100644 (file)
index 0000000..eac1054
--- /dev/null
@@ -0,0 +1,66 @@
+/** @file\r
+  Implement the getsockopt API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Get the socket options\r
+\r
+  @param [in] s               Socket file descriptor returned from ::socket.\r
+  @param [in] level           Option protocol level\r
+  @param [in] option_name     Name of the option\r
+  @param [out] option_value   Buffer to receive the option value\r
+  @param [in,out] option_len  Length of the buffer in bytes,\r
+                              upon return length of the option value in bytes\r
+\r
+  @retval   Zero (0) upon success\r
+  @retval   Minus one (-1) upon failure, errno set with additional error information\r
+\r
+**/\r
+int\r
+getsockopt (\r
+  IN int s,\r
+  IN int level,\r
+  IN int option_name,\r
+  OUT void * __restrict option_value,\r
+  IN OUT socklen_t * __restrict option_len\r
+  )\r
+{\r
+  int OptionStatus;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+  \r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Get the socket option\r
+    //\r
+    Status = pSocketProtocol->pfnOptionGet ( pSocketProtocol,\r
+                                             level,\r
+                                             option_name,\r
+                                             option_value,\r
+                                             option_len,\r
+                                             &errno );\r
+  }\r
+  \r
+  //\r
+  //  Return the operation stauts\r
+  //\r
+  OptionStatus = ( 0 == errno ) ? 0 : -1;\r
+  return OptionStatus;\r
+}\r
diff --git a/StdLib/BsdSocketLib/herror.c b/StdLib/BsdSocketLib/herror.c
new file mode 100644 (file)
index 0000000..e1c9b41
--- /dev/null
@@ -0,0 +1,134 @@
+/*\r
+ * Copyright (c) 1987, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ * \r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)herror.c   8.1 (Berkeley) 6/4/93";\r
+static char rcsid[] = "$Id: herror.c,v 1.1.1.1 2003/11/19 01:51:28 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/uio.h>\r
+#include <netdb.h>\r
+#include <string.h>\r
+#include <stdio.h>\r
+#include <unistd.h>\r
+\r
+const char *h_errlist[] = {\r
+       "Resolver Error 0 (no error)",\r
+       "Unknown host",                         /* 1 HOST_NOT_FOUND */\r
+       "Host name lookup failure",             /* 2 TRY_AGAIN */\r
+       "Unknown server error",                 /* 3 NO_RECOVERY */\r
+       "No address associated with name",      /* 4 NO_ADDRESS */\r
+};\r
+int    h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };\r
+\r
+int    h_errno;\r
+\r
+const char *\r
+hstrerror(\r
+  int err\r
+  );\r
+\r
+/*\r
+ * herror --\r
+ *     print the error indicated by the h_errno value.\r
+ */\r
+void\r
+herror(\r
+       const char *s\r
+       )\r
+{\r
+       struct iovec iov[4];\r
+       register struct iovec *v = iov;\r
+       int             i;\r
+\r
+       if (s && *s) {\r
+               v->iov_base = (char *)s;\r
+               v->iov_len = strlen(s);\r
+               v++;\r
+               v->iov_base = ": ";\r
+               v->iov_len = 2;\r
+               v++;\r
+       }\r
+       v->iov_base = (char *)hstrerror(h_errno);\r
+       v->iov_len = strlen(v->iov_base);\r
+       v++;\r
+       v->iov_base = "\n";\r
+       v->iov_len = 1;\r
+#ifdef _ORG_FREEBSD_\r
+       writev(STDERR_FILENO, iov, (v - iov) + 1);\r
+#else\r
+       for (i = 0; i < (v - iov) + 1; i++)\r
+               fprintf( stderr, iov[i].iov_base);\r
+#endif\r
+\r
+}\r
+\r
+const char *\r
+hstrerror(\r
+       int err\r
+       )\r
+{\r
+       if (err < 0)\r
+               return ("Resolver internal error");\r
+       else if (err < h_nerr)\r
+               return (h_errlist[err]);\r
+       return ("Unknown resolver error");\r
+}\r
diff --git a/StdLib/BsdSocketLib/inet_net_ntop.c b/StdLib/BsdSocketLib/inet_net_ntop.c
new file mode 100644 (file)
index 0000000..3925727
--- /dev/null
@@ -0,0 +1,142 @@
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static const char orig_rcsid[] = "From Id: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp";\r
+static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.1.1.1 2003/11/19 01:51:29 kyu3 Exp $";\r
+#endif\r
+\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+\r
+#include <errno.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#ifdef SPRINTF_CHAR\r
+# define SPRINTF(x) strlen(sprintf/**/x)\r
+#else\r
+# define SPRINTF(x) ((size_t)sprintf x)\r
+#endif\r
+\r
+static char *  inet_net_ntop_ipv4 (const u_char *src, int bits,\r
+                                       char *dst, size_t size);\r
+\r
+/*\r
+ * char *\r
+ * inet_net_ntop(af, src, bits, dst, size)\r
+ *     convert network number from network to presentation format.\r
+ *     generates CIDR style result always.\r
+ * return:\r
+ *     pointer to dst, or NULL if an error occurred (check errno).\r
+ * author:\r
+ *     Paul Vixie (ISC), July 1996\r
+ */\r
+char *\r
+inet_net_ntop(\r
+       int af,\r
+       const void *src,\r
+       int bits,\r
+       char *dst,\r
+       size_t size\r
+       )\r
+{\r
+       switch (af) {\r
+       case AF_INET:\r
+               return (inet_net_ntop_ipv4(src, bits, dst, size));\r
+       default:\r
+               errno = EAFNOSUPPORT;\r
+               return (NULL);\r
+       }\r
+}\r
+\r
+/*\r
+ * static char *\r
+ * inet_net_ntop_ipv4(src, bits, dst, size)\r
+ *     convert IPv4 network number from network to presentation format.\r
+ *     generates CIDR style result always.\r
+ * return:\r
+ *     pointer to dst, or NULL if an error occurred (check errno).\r
+ * note:\r
+ *     network byte order assumed.  this means 192.5.5.240/28 has\r
+ *     0x11110000 in its fourth octet.\r
+ * author:\r
+ *     Paul Vixie (ISC), July 1996\r
+ */\r
+static char *\r
+inet_net_ntop_ipv4(\r
+       const u_char *src,\r
+       int bits,\r
+       char *dst,\r
+       size_t size\r
+       )\r
+{\r
+       char *odst = dst;\r
+       char *t;\r
+       u_int m;\r
+       int b;\r
+\r
+       if (bits < 0 || bits > 32) {\r
+               errno = EINVAL;\r
+               return (NULL);\r
+       }\r
+       if (bits == 0) {\r
+               if (size < sizeof "0")\r
+                       goto emsgsize;\r
+               *dst++ = '0';\r
+               *dst = '\0';\r
+       }\r
+\r
+       /* Format whole octets. */\r
+       for (b = bits / 8; b > 0; b--) {\r
+               if (size < sizeof "255.")\r
+                       goto emsgsize;\r
+               t = dst;\r
+               dst += SPRINTF((dst, "%u", *src++));\r
+               if (b > 1) {\r
+                       *dst++ = '.';\r
+                       *dst = '\0';\r
+               }\r
+               size -= (size_t)(dst - t);\r
+       }\r
+\r
+       /* Format partial octet. */\r
+       b = bits % 8;\r
+       if (b > 0) {\r
+               if (size < sizeof ".255")\r
+                       goto emsgsize;\r
+               t = dst;\r
+               if (dst != odst)\r
+                       *dst++ = '.';\r
+               m = ((1 << b) - 1) << (8 - b);\r
+               dst += SPRINTF((dst, "%u", *src & m));\r
+               size -= (size_t)(dst - t);\r
+       }\r
+\r
+       /* Format CIDR /width. */\r
+       if (size < sizeof "/32")\r
+               goto emsgsize;\r
+       dst += SPRINTF((dst, "/%u", bits));\r
+       return (odst);\r
+\r
+ emsgsize:\r
+       errno = EMSGSIZE;\r
+       return (NULL);\r
+}\r
diff --git a/StdLib/BsdSocketLib/inet_net_pton.c b/StdLib/BsdSocketLib/inet_net_pton.c
new file mode 100644 (file)
index 0000000..4e4424a
--- /dev/null
@@ -0,0 +1,252 @@
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 1.8 1996/11/21 10:28:12 vixie Exp $";\r
+static const char rcsid[] = "$Id: inet_net_pton.c,v 1.1.1.1 2003/11/19 01:51:29 kyu3 Exp $";\r
+#endif\r
+\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+\r
+#include <assert.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#ifdef SPRINTF_CHAR\r
+# define SPRINTF(x) strlen(sprintf/**/x)\r
+#else\r
+# define SPRINTF(x) ((size_t)sprintf x)\r
+#endif\r
+\r
+static int     inet_net_pton_ipv4 (const char *src, u_char *dst,\r
+                                       size_t size);\r
+\r
+/*\r
+ * static int\r
+ * inet_net_pton(af, src, dst, size)\r
+ *     convert network number from presentation to network format.\r
+ *     accepts hex octets, hex strings, decimal octets, and /CIDR.\r
+ *     "size" is in bytes and describes "dst".\r
+ * return:\r
+ *     number of bits, either imputed classfully or specified with /CIDR,\r
+ *     or -1 if some failure occurred (check errno).  ENOENT means it was\r
+ *     not a valid network specification.\r
+ * author:\r
+ *     Paul Vixie (ISC), June 1996\r
+ */\r
+int\r
+inet_net_pton(\r
+       int af,\r
+       const char *src,\r
+       void *dst,\r
+       size_t size\r
+       )\r
+{\r
+       switch (af) {\r
+       case AF_INET:\r
+               return (inet_net_pton_ipv4(src, dst, size));\r
+       default:\r
+               errno = EAFNOSUPPORT;\r
+               return (-1);\r
+       }\r
+}\r
+\r
+/*\r
+ * static int\r
+ * inet_net_pton_ipv4(src, dst, size)\r
+ *     convert IPv4 network number from presentation to network format.\r
+ *     accepts hex octets, hex strings, decimal octets, and /CIDR.\r
+ *     "size" is in bytes and describes "dst".\r
+ * return:\r
+ *     number of bits, either imputed classfully or specified with /CIDR,\r
+ *     or -1 if some failure occurred (check errno).  ENOENT means it was\r
+ *     not an IPv4 network specification.\r
+ * note:\r
+ *     network byte order assumed.  this means 192.5.5.240/28 has\r
+ *     0x11110000 in its fourth octet.\r
+ * author:\r
+ *     Paul Vixie (ISC), June 1996\r
+ */\r
+static int\r
+inet_net_pton_ipv4(\r
+       const char *src,\r
+       u_char *dst,\r
+       size_t size\r
+       )\r
+{\r
+       static const char xdigits[] = "0123456789abcdef";\r
+       static const char digits[] = "0123456789";\r
+       int n;\r
+  int ch;\r
+  int tmp;\r
+  int dirty;\r
+  int bits;\r
+       const u_char *odst = dst;\r
+\r
+       ch = *src++;\r
+       if (ch == '0' && (src[0] == 'x' || src[0] == 'X')\r
+           && isascii(src[1]) && isxdigit(src[1])) {\r
+               /* Hexadecimal: Eat nybble string. */\r
+               if (size <= 0)\r
+                       goto emsgsize;\r
+               *dst = 0, dirty = 0;\r
+               src++;  /* skip x or X. */\r
+               while ((ch = *src++) != '\0' &&\r
+                      isascii(ch) && isxdigit(ch)) {\r
+                       if (isupper(ch))\r
+                               ch = tolower(ch);\r
+                       n = (int)(strchr(xdigits, ch) - xdigits);\r
+                       assert(n >= 0 && n <= 15);\r
+                       *dst |= n;\r
+                       if (!dirty++)\r
+                               *dst <<= 4;\r
+                       else if (size-- > 0)\r
+                               *++dst = 0, dirty = 0;\r
+                       else\r
+                               goto emsgsize;\r
+               }\r
+               if (dirty)\r
+                       size--;\r
+       } else if (isascii(ch) && isdigit(ch)) {\r
+               /* Decimal: eat dotted digit string. */\r
+               for (;;) {\r
+                       tmp = 0;\r
+                       do {\r
+                               n = (int)(strchr(digits, ch) - digits);\r
+                               assert(n >= 0 && n <= 9);\r
+                               tmp *= 10;\r
+                               tmp += n;\r
+                               if (tmp > 255)\r
+                                       goto enoent;\r
+                       } while ((ch = *src++) != '\0' &&\r
+                                isascii(ch) && isdigit(ch));\r
+                       if (size-- <= 0)\r
+                               goto emsgsize;\r
+                       *dst++ = (u_char) tmp;\r
+                       if (ch == '\0' || ch == '/')\r
+                               break;\r
+                       if (ch != '.')\r
+                               goto enoent;\r
+                       ch = *src++;\r
+                       if (!isascii(ch) || !isdigit(ch))\r
+                               goto enoent;\r
+               }\r
+       } else\r
+               goto enoent;\r
+\r
+       bits = -1;\r
+       if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {\r
+               /* CIDR width specifier.  Nothing can follow it. */\r
+               ch = *src++;    /* Skip over the /. */\r
+               bits = 0;\r
+               do {\r
+                       n = (int)(strchr(digits, ch) - digits);\r
+                       assert(n >= 0 && n <= 9);\r
+                       bits *= 10;\r
+                       bits += n;\r
+               } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));\r
+               if (ch != '\0')\r
+                       goto enoent;\r
+               if (bits > 32)\r
+                       goto emsgsize;\r
+       }\r
+\r
+       /* Firey death and destruction unless we prefetched EOS. */\r
+       if (ch != '\0')\r
+               goto enoent;\r
+\r
+       /* If nothing was written to the destination, we found no address. */\r
+       if (dst == odst)\r
+               goto enoent;\r
+       /* If no CIDR spec was given, infer width from net class. */\r
+       if (bits == -1) {\r
+               if (*odst >= 240)       /* Class E */\r
+                       bits = 32;\r
+               else if (*odst >= 224)  /* Class D */\r
+                       bits = 4;\r
+               else if (*odst >= 192)  /* Class C */\r
+                       bits = 24;\r
+               else if (*odst >= 128)  /* Class B */\r
+                       bits = 16;\r
+               else                    /* Class A */\r
+                       bits = 8;\r
+               /* If imputed mask is narrower than specified octets, widen. */\r
+               if (bits >= 8 && bits < ((dst - odst) * 8))\r
+                       bits = (int)(dst - odst) * 8;\r
+       }\r
+       /* Extend network to cover the actual mask. */\r
+       while (bits > ((dst - odst) * 8)) {\r
+               if (size-- <= 0)\r
+                       goto emsgsize;\r
+               *dst++ = '\0';\r
+       }\r
+       return (bits);\r
+\r
+ enoent:\r
+       errno = ENOENT;\r
+       return (-1);\r
+\r
+ emsgsize:\r
+       errno = EMSGSIZE;\r
+       return (-1);\r
+}\r
diff --git a/StdLib/BsdSocketLib/inet_neta.c b/StdLib/BsdSocketLib/inet_neta.c
new file mode 100644 (file)
index 0000000..b313b13
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static const char orig_rcsid[] = "From Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp";\r
+static const char rcsid[] = "$Id: inet_neta.c,v 1.1.1.1 2003/11/19 01:51:29 kyu3 Exp $";\r
+#endif\r
+\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+\r
+#include <errno.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#ifdef SPRINTF_CHAR\r
+# define SPRINTF(x) strlen(sprintf/**/x)\r
+#else\r
+# define SPRINTF(x) ((size_t)sprintf x)\r
+#endif\r
+\r
+/*\r
+ * char *\r
+ * inet_neta(src, dst, size)\r
+ *     format a u_long network number into presentation format.\r
+ * return:\r
+ *     pointer to dst, or NULL if an error occurred (check errno).\r
+ * note:\r
+ *     format of ``src'' is as for inet_network().\r
+ * author:\r
+ *     Paul Vixie (ISC), July 1996\r
+ */\r
+char *\r
+inet_neta(\r
+       u_long src,\r
+       char *dst,\r
+       size_t size\r
+       )\r
+{\r
+       char *odst = dst;\r
+       char *tp;\r
+\r
+       while (src & 0xffffffff) {\r
+               u_char b = (u_char)((src & 0xff000000) >> 24);\r
+\r
+               src <<= 8;\r
+               if (b) {\r
+                       if (size < sizeof "255.")\r
+                               goto emsgsize;\r
+                       tp = dst;\r
+                       dst += SPRINTF((dst, "%u", b));\r
+                       if (src != 0L) {\r
+                               *dst++ = '.';\r
+                               *dst = '\0';\r
+                       }\r
+                       size -= (size_t)(dst - tp);\r
+               }\r
+       }\r
+       if (dst == odst) {\r
+               if (size < sizeof "0.0.0.0")\r
+                       goto emsgsize;\r
+               strcpy(dst, "0.0.0.0");\r
+       }\r
+       return (odst);\r
+\r
+ emsgsize:\r
+       errno = EMSGSIZE;\r
+       return (NULL);\r
+}\r
diff --git a/StdLib/BsdSocketLib/inet_pton.c b/StdLib/BsdSocketLib/inet_pton.c
new file mode 100644 (file)
index 0000000..32e1ab8
--- /dev/null
@@ -0,0 +1,257 @@
+/* Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char rcsid[] = "$Id: inet_pton.c,v 1.1.1.1 2003/11/19 01:51:30 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+#include <string.h>\r
+#include <errno.h>\r
+\r
+/*\r
+ * WARNING: Don't even consider trying to compile this on a system where\r
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.\r
+ */\r
+\r
+static int     inet_pton4 (const char *src, u_char *dst);\r
+static int     inet_pton6 (const char *src, u_char *dst);\r
+\r
+/* int\r
+ * inet_pton(af, src, dst)\r
+ *     convert from presentation format (which usually means ASCII printable)\r
+ *     to network format (which is usually some kind of binary format).\r
+ * return:\r
+ *     1 if the address was valid for the specified address family\r
+ *     0 if the address wasn't valid (`dst' is untouched in this case)\r
+ *     -1 if some other error occurred (`dst' is untouched in this case, too)\r
+ * author:\r
+ *     Paul Vixie, 1996.\r
+ */\r
+int\r
+inet_pton(\r
+       int af,\r
+       const char *src,\r
+       void *dst\r
+       )\r
+{\r
+       switch (af) {\r
+       case AF_INET:\r
+               return (inet_pton4(src, dst));\r
+       case AF_INET6:\r
+               return (inet_pton6(src, dst));\r
+       default:\r
+               errno = EAFNOSUPPORT;\r
+               return (-1);\r
+       }\r
+       /* NOTREACHED */\r
+}\r
+\r
+/* int\r
+ * inet_pton4(src, dst)\r
+ *     like inet_aton() but without all the hexadecimal and shorthand.\r
+ * return:\r
+ *     1 if `src' is a valid dotted quad, else 0.\r
+ * notice:\r
+ *     does not touch `dst' unless it's returning 1.\r
+ * author:\r
+ *     Paul Vixie, 1996.\r
+ */\r
+static int\r
+inet_pton4(\r
+       const char *src,\r
+       u_char *dst\r
+       )\r
+{\r
+       static const char digits[] = "0123456789";\r
+       int saw_digit, octets, ch;\r
+       u_char tmp[NS_INADDRSZ], *tp;\r
+\r
+       saw_digit = 0;\r
+       octets = 0;\r
+       *(tp = tmp) = 0;\r
+       while ((ch = *src++) != '\0') {\r
+               const char *pch;\r
+\r
+               if ((pch = strchr(digits, ch)) != NULL) {\r
+                       u_int new = *tp * 10 + (u_int)(pch - digits);\r
+\r
+                       if (new > 255)\r
+                               return (0);\r
+                       *tp = (u_char)new;\r
+                       if (! saw_digit) {\r
+                               if (++octets > 4)\r
+                                       return (0);\r
+                               saw_digit = 1;\r
+                       }\r
+               } else if (ch == '.' && saw_digit) {\r
+                       if (octets == 4)\r
+                               return (0);\r
+                       *++tp = 0;\r
+                       saw_digit = 0;\r
+               } else\r
+                       return (0);\r
+       }\r
+       if (octets < 4)\r
+               return (0);\r
+\r
+       memcpy(dst, tmp, NS_INADDRSZ);\r
+       return (1);\r
+}\r
+\r
+/* int\r
+ * inet_pton6(src, dst)\r
+ *     convert presentation level address to network order binary form.\r
+ * return:\r
+ *     1 if `src' is a valid [RFC1884 2.2] address, else 0.\r
+ * notice:\r
+ *     (1) does not touch `dst' unless it's returning 1.\r
+ *     (2) :: in a full address is silently ignored.\r
+ * credit:\r
+ *     inspired by Mark Andrews.\r
+ * author:\r
+ *     Paul Vixie, 1996.\r
+ */\r
+static int\r
+inet_pton6(\r
+       const char *src,\r
+       u_char *dst\r
+       )\r
+{\r
+       static const char xdigits_l[] = "0123456789abcdef",\r
+                         xdigits_u[] = "0123456789ABCDEF";\r
+       u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;\r
+       const char *xdigits, *curtok;\r
+       int ch, saw_xdigit;\r
+       u_int val;\r
+\r
+       memset((tp = tmp), '\0', NS_IN6ADDRSZ);\r
+       endp = tp + NS_IN6ADDRSZ;\r
+       colonp = NULL;\r
+       /* Leading :: requires some special handling. */\r
+       if (*src == ':')\r
+               if (*++src != ':')\r
+                       return (0);\r
+       curtok = src;\r
+       saw_xdigit = 0;\r
+       val = 0;\r
+       while ((ch = *src++) != '\0') {\r
+               const char *pch;\r
+\r
+               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)\r
+                       pch = strchr((xdigits = xdigits_u), ch);\r
+               if (pch != NULL) {\r
+                       val <<= 4;\r
+                       val |= (pch - xdigits);\r
+                       if (val > 0xffff)\r
+                               return (0);\r
+                       saw_xdigit = 1;\r
+                       continue;\r
+               }\r
+               if (ch == ':') {\r
+                       curtok = src;\r
+                       if (!saw_xdigit) {\r
+                               if (colonp)\r
+                                       return (0);\r
+                               colonp = tp;\r
+                               continue;\r
+                       }\r
+                       if (tp + NS_INT16SZ > endp)\r
+                               return (0);\r
+                       *tp++ = (u_char) (val >> 8) & 0xff;\r
+                       *tp++ = (u_char) val & 0xff;\r
+                       saw_xdigit = 0;\r
+                       val = 0;\r
+                       continue;\r
+               }\r
+               if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&\r
+                   inet_pton4(curtok, tp) > 0) {\r
+                       tp += NS_INADDRSZ;\r
+                       saw_xdigit = 0;\r
+                       break;  /* '\0' was seen by inet_pton4(). */\r
+               }\r
+               return (0);\r
+       }\r
+       if (saw_xdigit) {\r
+               if (tp + NS_INT16SZ > endp)\r
+                       return (0);\r
+               *tp++ = (u_char) (val >> 8) & 0xff;\r
+               *tp++ = (u_char) val & 0xff;\r
+       }\r
+       if (colonp != NULL) {\r
+               /*\r
+                * Since some memmove()'s erroneously fail to handle\r
+                * overlapping regions, we'll do the shift by hand.\r
+                */\r
+               const int n = (int)(tp - colonp);\r
+               int i;\r
+\r
+               for (i = 1; i <= n; i++) {\r
+                       endp[- i] = colonp[n - i];\r
+                       colonp[n - i] = 0;\r
+               }\r
+               tp = endp;\r
+       }\r
+       if (tp != endp)\r
+               return (0);\r
+       memcpy(dst, tmp, NS_IN6ADDRSZ);\r
+       return (1);\r
+}\r
diff --git a/StdLib/BsdSocketLib/listen.c b/StdLib/BsdSocketLib/listen.c
new file mode 100644 (file)
index 0000000..5e14876
--- /dev/null
@@ -0,0 +1,65 @@
+/** @file\r
+  Implement the listen API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Establish the known port to listen for network connections.\r
+\r
+  The ::listen routine places the port into a state that enables connection\r
+  attempts.  Connections are placed into FIFO order in a queue to be serviced\r
+  by the application.  The application calls the ::accept routine to remove\r
+  the next connection from the queue and get the associated socket.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html">POSIX</a>\r
+  documentation for the bind routine is available online for reference.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] backlog   backlog specifies the maximum FIFO depth for the connections\r
+                        waiting for the application to call accept.  Connection attempts\r
+                        received while the queue is full are refused.\r
+\r
+  @returns    The listen routine returns zero (0) if successful and -1 upon failure.\r
+\r
+ **/\r
+int\r
+listen (\r
+  IN int s,\r
+  IN int backlog\r
+  )\r
+{\r
+  int ListenStatus;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Enable connections on the known port\r
+    //\r
+    Status = pSocketProtocol->pfnListen ( pSocketProtocol,\r
+                                          backlog,\r
+                                          &errno );\r
+  }\r
+\r
+  //\r
+  //  Return the operation stauts\r
+  //\r
+  ListenStatus = ( 0 == errno ) ? 0 : -1;\r
+  return ListenStatus;\r
+}\r
diff --git a/StdLib/BsdSocketLib/map_v4v6.c b/StdLib/BsdSocketLib/map_v4v6.c
new file mode 100644 (file)
index 0000000..5ad73c8
--- /dev/null
@@ -0,0 +1,135 @@
+/*\r
+ * ++Copyright++ 1985, 1988, 1993\r
+ * -\r
+ * Copyright (c) 1985, 1988, 1993\r
+ *    The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ * \r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * -\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ * \r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ * -\r
+ * --Copyright--\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)gethostnamadr.c    8.1 (Berkeley) 6/4/93";\r
+static char rcsid[] = "$Id: map_v4v6.c,v 1.1.1.1 2003/11/19 01:51:31 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#ifdef _ORG_FREEBSD_\r
+#include <syslog.h>\r
+#endif\r
+#include "Socklib_internals.h"\r
+\r
+typedef union {\r
+       int32_t al;\r
+       char ac;\r
+} align;\r
+\r
+void\r
+_map_v4v6_address(const char *src, char *dst)\r
+{\r
+       u_char *p = (u_char *)dst;\r
+       char tmp[INADDRSZ];\r
+       int i;\r
+\r
+       /* Stash a temporary copy so our caller can update in place. */\r
+       bcopy(src, tmp, INADDRSZ);\r
+       /* Mark this ipv6 addr as a mapped ipv4. */\r
+       for (i = 0; i < 10; i++)\r
+               *p++ = 0x00;\r
+       *p++ = 0xff;\r
+       *p++ = 0xff;\r
+       /* Retrieve the saved copy and we're done. */\r
+       bcopy(tmp, (void*)p, INADDRSZ);\r
+}\r
+\r
+void\r
+_map_v4v6_hostent(struct hostent *hp, char **bpp, int *lenp)\r
+{\r
+       char **ap;\r
+\r
+       if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)\r
+               return;\r
+       hp->h_addrtype = AF_INET6;\r
+       hp->h_length = IN6ADDRSZ;\r
+       for (ap = hp->h_addr_list; *ap; ap++) {\r
+               int i = (int)(sizeof(align) - ((size_t)*bpp % sizeof(align)));\r
+\r
+               if (*lenp < (i + IN6ADDRSZ)) {\r
+                       /* Out of memory.  Truncate address list here.  XXX */\r
+                       *ap = NULL;\r
+                       return;\r
+               }\r
+               *bpp += i;\r
+               *lenp -= i;\r
+               _map_v4v6_address(*ap, *bpp);\r
+               *ap = *bpp;\r
+               *bpp += IN6ADDRSZ;\r
+               *lenp -= IN6ADDRSZ;\r
+       }\r
+}\r
diff --git a/StdLib/BsdSocketLib/ns_addr.c b/StdLib/BsdSocketLib/ns_addr.c
new file mode 100644 (file)
index 0000000..81fd625
--- /dev/null
@@ -0,0 +1,240 @@
+/*\r
+ * Copyright (c) 1986, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to Berkeley by\r
+ * J.Q. Johnson.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ * \r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)ns_addr.c  8.1 (Berkeley) 6/7/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <netns/ns.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+static struct ns_addr addr, zero_addr;\r
+\r
+static void Field(), cvtbase();\r
+\r
+struct ns_addr\r
+ns_addr(\r
+       const char *name\r
+       )\r
+{\r
+       char separator;\r
+       char *hostname, *socketname, *cp;\r
+       char buf[50];\r
+\r
+       (void)strncpy(buf, name, sizeof(buf) - 1);\r
+       buf[sizeof(buf) - 1] = '\0';\r
+\r
+       /*\r
+        * First, figure out what he intends as a field separtor.\r
+        * Despite the way this routine is written, the prefered\r
+        * form  2-272.AA001234H.01777, i.e. XDE standard.\r
+        * Great efforts are made to insure backward compatability.\r
+        */\r
+       if ((hostname = strchr(buf, '#')) != NULL)\r
+               separator = '#';\r
+       else {\r
+               hostname = strchr(buf, '.');\r
+               if ((cp = strchr(buf, ':')) &&\r
+                   ((hostname && cp < hostname) || (hostname == 0))) {\r
+                       hostname = cp;\r
+                       separator = ':';\r
+               } else\r
+                       separator = '.';\r
+       }\r
+       if (hostname)\r
+               *hostname++ = 0;\r
+\r
+       addr = zero_addr;\r
+       Field(buf, addr.x_net.c_net, 4);\r
+       if (hostname == 0)\r
+               return (addr);  /* No separator means net only */\r
+\r
+       socketname = strchr(hostname, separator);\r
+       if (socketname) {\r
+               *socketname++ = 0;\r
+               Field(socketname, (u_char *)&addr.x_port, 2);\r
+       }\r
+\r
+       Field(hostname, addr.x_host.c_host, 6);\r
+\r
+       return (addr);\r
+}\r
+\r
+static void\r
+Field(\r
+       char *buf,\r
+       u_char *out,\r
+       int len\r
+       )\r
+{\r
+       register char *bp = buf;\r
+       int i, ibase, base16 = 0, base10 = 0, clen = 0;\r
+       int hb[6], *hp;\r
+       char *fmt;\r
+\r
+       /*\r
+        * first try 2-273#2-852-151-014#socket\r
+        */\r
+       if ((*buf != '-') &&\r
+           (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",\r
+                       &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {\r
+               cvtbase(1000L, 256, hb, i, out, len);\r
+               return;\r
+       }\r
+       /*\r
+        * try form 8E1#0.0.AA.0.5E.E6#socket\r
+        */\r
+       if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",\r
+                       &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {\r
+               cvtbase(256L, 256, hb, i, out, len);\r
+               return;\r
+       }\r
+       /*\r
+        * try form 8E1#0:0:AA:0:5E:E6#socket\r
+        */\r
+       if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",\r
+                       &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {\r
+               cvtbase(256L, 256, hb, i, out, len);\r
+               return;\r
+       }\r
+       /*\r
+        * This is REALLY stretching it but there was a\r
+        * comma notation separting shorts -- definitely non standard\r
+        */\r
+       if (1 < (i = sscanf(buf,"%x,%x,%x",\r
+                       &hb[0], &hb[1], &hb[2]))) {\r
+               hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);\r
+               hb[2] = htons(hb[2]);\r
+               cvtbase(65536L, 256, hb, i, out, len);\r
+               return;\r
+       }\r
+\r
+       /* Need to decide if base 10, 16 or 8 */\r
+       while (*bp) switch (*bp++) {\r
+\r
+       case '0': case '1': case '2': case '3': case '4': case '5':\r
+       case '6': case '7': case '-':\r
+               break;\r
+\r
+       case '8': case '9':\r
+               base10 = 1;\r
+               break;\r
+\r
+       case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
+       case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
+               base16 = 1;\r
+               break;\r
+\r
+       case 'x': case 'X':\r
+               *--bp = '0';\r
+               base16 = 1;\r
+               break;\r
+\r
+       case 'h': case 'H':\r
+               base16 = 1;\r
+               /* fall into */\r
+\r
+       default:\r
+               *--bp = 0; /* Ends Loop */\r
+       }\r
+       if (base16) {\r
+               fmt = "%3x";\r
+               ibase = 4096;\r
+       } else if (base10 == 0 && *buf == '0') {\r
+               fmt = "%3o";\r
+               ibase = 512;\r
+       } else {\r
+               fmt = "%3d";\r
+               ibase = 1000;\r
+       }\r
+\r
+       for (bp = buf; *bp++; ) clen++;\r
+       if (clen == 0) clen++;\r
+       if (clen > 18) clen = 18;\r
+       i = ((clen - 1) / 3) + 1;\r
+       bp = clen + buf - 3;\r
+       hp = hb + i - 1;\r
+\r
+       while (hp > hb) {\r
+               (void)sscanf(bp, fmt, hp);\r
+               bp[0] = 0;\r
+               hp--;\r
+               bp -= 3;\r
+       }\r
+       (void)sscanf(buf, fmt, hp);\r
+       cvtbase((long)ibase, 256, hb, i, out, len);\r
+}\r
+\r
+static void\r
+cvtbase(\r
+       long oldbase,\r
+       int newbase,\r
+       int input[],\r
+       int inlen,\r
+       unsigned char result[],\r
+       int reslen\r
+       )\r
+{\r
+       int d, e;\r
+       long sum;\r
+\r
+       e = 1;\r
+       while (e > 0 && reslen > 0) {\r
+               d = 0; e = 0; sum = 0;\r
+               /* long division: input=input/newbase */\r
+               while (d < inlen) {\r
+                       sum = sum*oldbase + (long) input[d];\r
+                       e += (sum > 0);\r
+                       input[d++] = sum / newbase;\r
+                       sum %= newbase;\r
+               }\r
+               result[--reslen] = (u_char)sum; /* accumulate remainder */\r
+       }\r
+       for (d=0; d < reslen; d++)\r
+               result[d] = 0;\r
+}\r
diff --git a/StdLib/BsdSocketLib/ns_name.c b/StdLib/BsdSocketLib/ns_name.c
new file mode 100644 (file)
index 0000000..9303b3f
--- /dev/null
@@ -0,0 +1,633 @@
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#ifndef lint\r
+static char rcsid[] = "$Id: ns_name.c,v 1.1.1.1 2003/11/19 01:51:32 kyu3 Exp $";\r
+#endif\r
+\r
+#include <sys/types.h>\r
+\r
+#include <netinet/in.h>\r
+#include <arpa/nameser.h>\r
+\r
+#include <errno.h>\r
+#include <resolv.h>\r
+#include <string.h>\r
+\r
+/* Data. */\r
+\r
+static char            digits[] = "0123456789";\r
+\r
+/* Forward. */\r
+\r
+static int             special(int);\r
+static int             printable(int);\r
+static int             dn_find(const u_char *, const u_char *,\r
+                               const u_char * const *,\r
+                               const u_char * const *);\r
+\r
+/* Public. */\r
+\r
+/*\r
+ * ns_name_ntop(src, dst, dstsiz)\r
+ *     Convert an encoded domain name to printable ascii as per RFC1035.\r
+ * return:\r
+ *     Number of bytes written to buffer, or -1 (with errno set)\r
+ * notes:\r
+ *     The root is returned as "."\r
+ *     All other domains are returned in non absolute form\r
+ */\r
+int\r
+ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {\r
+       const u_char *cp;\r
+       char *dn, *eom;\r
+       u_char c;\r
+       u_int n;\r
+\r
+       cp = src;\r
+       dn = dst;\r
+       eom = dst + dstsiz;\r
+\r
+       while ((n = *cp++) != 0) {\r
+               if ((n & NS_CMPRSFLGS) != 0) {\r
+                       /* Some kind of compression pointer. */\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               if (dn != dst) {\r
+                       if (dn >= eom) {\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+                       *dn++ = '.';\r
+               }\r
+               if (dn + n >= eom) {\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               for ((void)NULL; n > 0; n--) {\r
+                       c = *cp++;\r
+                       if (special(c)) {\r
+                               if (dn + 1 >= eom) {\r
+                                       errno = EMSGSIZE;\r
+                                       return (-1);\r
+                               }\r
+                               *dn++ = '\\';\r
+                               *dn++ = (char)c;\r
+                       } else if (!printable(c)) {\r
+                               if (dn + 3 >= eom) {\r
+                                       errno = EMSGSIZE;\r
+                                       return (-1);\r
+                               }\r
+                               *dn++ = '\\';\r
+                               *dn++ = digits[c / 100];\r
+                               *dn++ = digits[(c % 100) / 10];\r
+                               *dn++ = digits[c % 10];\r
+                       } else {\r
+                               if (dn >= eom) {\r
+                                       errno = EMSGSIZE;\r
+                                       return (-1);\r
+                               }\r
+                               *dn++ = (char)c;\r
+                       }\r
+               }\r
+       }\r
+       if (dn == dst) {\r
+               if (dn >= eom) {\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               *dn++ = '.';\r
+       }\r
+       if (dn >= eom) {\r
+               errno = EMSGSIZE;\r
+               return (-1);\r
+       }\r
+       *dn++ = '\0';\r
+       return ((int)(dn - dst));\r
+}\r
+\r
+/*\r
+ * ns_name_pton(src, dst, dstsiz)\r
+ *     Convert a ascii string into an encoded domain name as per RFC1035.\r
+ * return:\r
+ *     -1 if it fails\r
+ *     1 if string was fully qualified\r
+ *     0 is string was not fully qualified\r
+ * notes:\r
+ *     Enforces label and domain length limits.\r
+ */\r
+\r
+int\r
+ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {\r
+       u_char *label, *bp, *eom;\r
+       int c, n, escaped;\r
+       char *cp;\r
+\r
+       escaped = 0;\r
+       bp = dst;\r
+       eom = dst + dstsiz;\r
+       label = bp++;\r
+\r
+       while ((c = *src++) != 0) {\r
+               if (escaped) {\r
+                       if ((cp = strchr(digits, c)) != NULL) {\r
+                               n = (int)(cp - digits) * 100;\r
+                               if ((c = *src++) == 0 ||\r
+                                   (cp = strchr(digits, c)) == NULL) {\r
+                                       errno = EMSGSIZE;\r
+                                       return (-1);\r
+                               }\r
+                               n += (int)(cp - digits) * 10;\r
+                               if ((c = *src++) == 0 ||\r
+                                   (cp = strchr(digits, c)) == NULL) {\r
+                                       errno = EMSGSIZE;\r
+                                       return (-1);\r
+                               }\r
+                               n += (int)(cp - digits);\r
+                               if (n > 255) {\r
+                                       errno = EMSGSIZE;\r
+                                       return (-1);\r
+                               }\r
+                               c = n;\r
+                       }\r
+                       escaped = 0;\r
+               } else if (c == '\\') {\r
+                       escaped = 1;\r
+                       continue;\r
+               } else if (c == '.') {\r
+                       c = ((int)(bp - label) - 1);\r
+                       if ((c & NS_CMPRSFLGS) != 0) {  /* Label too big. */\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+                       if (label >= eom) {\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+                       *label = (u_char)c;\r
+                       /* Fully qualified ? */\r
+                       if (*src == '\0') {\r
+                               if (c != 0) {\r
+                                       if (bp >= eom) {\r
+                                               errno = EMSGSIZE;\r
+                                               return (-1);\r
+                                       }\r
+                                       *bp++ = '\0';\r
+                               }\r
+                               if ((bp - dst) > MAXCDNAME) {\r
+                                       errno = EMSGSIZE;\r
+                                       return (-1);\r
+                               }\r
+                               return (1);\r
+                       }\r
+                       if (c == 0) {\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+                       label = bp++;\r
+                       continue;\r
+               }\r
+               if (bp >= eom) {\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               *bp++ = (u_char)c;\r
+       }\r
+       c = ((int)(bp - label) - 1);\r
+       if ((c & NS_CMPRSFLGS) != 0) {          /* Label too big. */\r
+               errno = EMSGSIZE;\r
+               return (-1);\r
+       }\r
+       if (label >= eom) {\r
+               errno = EMSGSIZE;\r
+               return (-1);\r
+       }\r
+       *label = (u_char)c;\r
+       if (c != 0) {\r
+               if (bp >= eom) {\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               *bp++ = 0;\r
+       }\r
+       if ((bp - dst) > MAXCDNAME) {   /* src too big */\r
+               errno = EMSGSIZE;\r
+               return (-1);\r
+       }\r
+       return (0);\r
+}\r
+\r
+/*\r
+ * ns_name_unpack(msg, eom, src, dst, dstsiz)\r
+ *     Unpack a domain name from a message, source may be compressed.\r
+ * return:\r
+ *     -1 if it fails, or consumed octets if it succeeds.\r
+ */\r
+int\r
+ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,\r
+              u_char *dst, size_t dstsiz)\r
+{\r
+       const u_char *srcp, *dstlim;\r
+       u_char *dstp;\r
+       int n, len, checked;\r
+\r
+       len = -1;\r
+       checked = 0;\r
+       dstp = dst;\r
+       srcp = src;\r
+       dstlim = dst + dstsiz;\r
+       if (srcp < msg || srcp >= eom) {\r
+               errno = EMSGSIZE;\r
+               return (-1);\r
+       }\r
+       /* Fetch next label in domain name. */\r
+       while ((n = *srcp++) != 0) {\r
+               /* Check for indirection. */\r
+               switch (n & NS_CMPRSFLGS) {\r
+               case 0:\r
+                       /* Limit checks. */\r
+                       if (dstp + n + 1 >= dstlim || srcp + n >= eom) {\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+                       checked += n + 1;\r
+                       *dstp++ = (u_char)n;\r
+                       memcpy(dstp, srcp, n);\r
+                       dstp += n;\r
+                       srcp += n;\r
+                       break;\r
+\r
+               case NS_CMPRSFLGS:\r
+                       if (srcp >= eom) {\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+                       if (len < 0)\r
+                               len = (int)(srcp - src) + 1;\r
+                       srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));\r
+                       if (srcp < msg || srcp >= eom) {  /* Out of range. */\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+                       checked += 2;\r
+                       /*\r
+                        * Check for loops in the compressed name;\r
+                        * if we've looked at the whole message,\r
+                        * there must be a loop.\r
+                        */\r
+                       if (checked >= eom - msg) {\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+                       break;\r
+\r
+               default:\r
+                       errno = EMSGSIZE;\r
+                       return (-1);                    /* flag error */\r
+               }\r
+       }\r
+       *dstp = '\0';\r
+       if (len < 0)\r
+               len = (int)(srcp - src);\r
+       return (len);\r
+}\r
+\r
+/*\r
+ * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)\r
+ *     Pack domain name 'domain' into 'comp_dn'.\r
+ * return:\r
+ *     Size of the compressed name, or -1.\r
+ * notes:\r
+ *     'dnptrs' is an array of pointers to previous compressed names.\r
+ *     dnptrs[0] is a pointer to the beginning of the message. The array\r
+ *     ends with NULL.\r
+ *     'lastdnptr' is a pointer to the end of the array pointed to\r
+ *     by 'dnptrs'.\r
+ * Side effects:\r
+ *     The list of pointers in dnptrs is updated for labels inserted into\r
+ *     the message as we compress the name.  If 'dnptr' is NULL, we don't\r
+ *     try to compress names. If 'lastdnptr' is NULL, we don't update the\r
+ *     list.\r
+ */\r
+int\r
+ns_name_pack(const u_char *src, u_char *dst, int dstsiz,\r
+            const u_char **dnptrs, const u_char **lastdnptr)\r
+{\r
+       u_char *dstp;\r
+       const u_char **cpp, **lpp, *eob, *msg;\r
+       const u_char *srcp;\r
+       int n, l;\r
+\r
+       srcp = src;\r
+       dstp = dst;\r
+       eob = dstp + dstsiz;\r
+       lpp = cpp = NULL;\r
+       if (dnptrs != NULL) {\r
+               if ((msg = *dnptrs++) != NULL) {\r
+                       for (cpp = dnptrs; *cpp != NULL; cpp++)\r
+                               (void)NULL;\r
+                       lpp = cpp;      /* end of list to search */\r
+               }\r
+       } else\r
+               msg = NULL;\r
+\r
+       /* make sure the domain we are about to add is legal */\r
+       l = 0;\r
+       do {\r
+               n = *srcp;\r
+               if ((n & NS_CMPRSFLGS) != 0) {\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               l += n + 1;\r
+               if (l > MAXCDNAME) {\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               srcp += n + 1;\r
+       } while (n != 0);\r
+\r
+       srcp = src;\r
+       do {\r
+               /* Look to see if we can use pointers. */\r
+               n = *srcp;\r
+               if (n != 0 && msg != NULL) {\r
+                       l = dn_find(srcp, msg, (const u_char * const *)dnptrs,\r
+                                   (const u_char * const *)lpp);\r
+                       if (l >= 0) {\r
+                               if (dstp + 1 >= eob) {\r
+                                       errno = EMSGSIZE;\r
+                                       return (-1);\r
+                               }\r
+                               *dstp++ = (u_char)((l >> 8) | NS_CMPRSFLGS );\r
+                               *dstp++ = (u_char)( l % 256 );\r
+                               return ((int)(dstp - dst));\r
+                       }\r
+                       /* Not found, save it. */\r
+                       if (lastdnptr != NULL && cpp < lastdnptr - 1 &&\r
+                           (dstp - msg) < 0x4000) {\r
+                               *cpp++ = dstp;\r
+                               *cpp = NULL;\r
+                       }\r
+               }\r
+               /* copy label to buffer */\r
+               if (n & NS_CMPRSFLGS) {         /* Should not happen. */\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               if (dstp + 1 + n >= eob) {\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               memcpy(dstp, srcp, n + 1);\r
+               srcp += n + 1;\r
+               dstp += n + 1;\r
+       } while (n != 0);\r
+\r
+       if (dstp > eob) {\r
+               if (msg != NULL)\r
+                       *lpp = NULL;\r
+               errno = EMSGSIZE;\r
+               return (-1);\r
+       } \r
+       return ((int)(dstp - dst));\r
+}\r
+\r
+/*\r
+ * ns_name_uncompress(msg, eom, src, dst, dstsiz)\r
+ *     Expand compressed domain name to presentation format.\r
+ * return:\r
+ *     Number of bytes read out of `src', or -1 (with errno set).\r
+ * note:\r
+ *     Root domain returns as "." not "".\r
+ */\r
+int\r
+ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,\r
+                  char *dst, size_t dstsiz)\r
+{\r
+       u_char tmp[NS_MAXCDNAME];\r
+       int n;\r
+       \r
+       if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)\r
+               return (-1);\r
+       if (ns_name_ntop(tmp, dst, dstsiz) == -1)\r
+               return (-1);\r
+       return (n);\r
+}\r
+\r
+/*\r
+ * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)\r
+ *     Compress a domain name into wire format, using compression pointers.\r
+ * return:\r
+ *     Number of bytes consumed in `dst' or -1 (with errno set).\r
+ * notes:\r
+ *     'dnptrs' is an array of pointers to previous compressed names.\r
+ *     dnptrs[0] is a pointer to the beginning of the message.\r
+ *     The list ends with NULL.  'lastdnptr' is a pointer to the end of the\r
+ *     array pointed to by 'dnptrs'. Side effect is to update the list of\r
+ *     pointers for labels inserted into the message as we compress the name.\r
+ *     If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'\r
+ *     is NULL, we don't update the list.\r
+ */\r
+int\r
+ns_name_compress(const char *src, u_char *dst, size_t dstsiz,\r
+                const u_char **dnptrs, const u_char **lastdnptr)\r
+{\r
+       u_char tmp[NS_MAXCDNAME];\r
+\r
+       if (ns_name_pton(src, tmp, sizeof tmp) == -1)\r
+               return (-1);\r
+       return (ns_name_pack(tmp, dst, (int)dstsiz, dnptrs, lastdnptr));\r
+}\r
+\r
+/*\r
+ * ns_name_skip(ptrptr, eom)\r
+ *     Advance *ptrptr to skip over the compressed name it points at.\r
+ * return:\r
+ *     0 on success, -1 (with errno set) on failure.\r
+ */\r
+int\r
+ns_name_skip(const u_char **ptrptr, const u_char *eom) {\r
+       const u_char *cp;\r
+       u_int n;\r
+\r
+       cp = *ptrptr;\r
+       while (cp < eom && (n = *cp++) != 0) {\r
+               /* Check for indirection. */\r
+               switch (n & NS_CMPRSFLGS) {\r
+               case 0:                 /* normal case, n == len */\r
+                       cp += n;\r
+                       continue;\r
+               case NS_CMPRSFLGS:      /* indirection */\r
+                       cp++;\r
+                       break;\r
+               default:                /* illegal type */\r
+                       errno = EMSGSIZE;\r
+                       return (-1);\r
+               }\r
+               break;\r
+       }\r
+       if (cp > eom) {\r
+               errno = EMSGSIZE;\r
+               return (-1);\r
+       }\r
+       *ptrptr = cp;\r
+       return (0);\r
+}\r
+\r
+/* Private. */\r
+\r
+/*\r
+ * special(ch)\r
+ *     Thinking in noninternationalized USASCII (per the DNS spec),\r
+ *     is this characted special ("in need of quoting") ?\r
+ * return:\r
+ *     boolean.\r
+ */\r
+static int\r
+special(int ch) {\r
+       switch (ch) {\r
+       case 0x22: /* '"' */\r
+       case 0x2E: /* '.' */\r
+       case 0x3B: /* ';' */\r
+       case 0x5C: /* '\\' */\r
+       /* Special modifiers in zone files. */\r
+       case 0x40: /* '@' */\r
+       case 0x24: /* '$' */\r
+               return (1);\r
+       default:\r
+               return (0);\r
+       }\r
+}\r
+\r
+/*\r
+ * printable(ch)\r
+ *     Thinking in noninternationalized USASCII (per the DNS spec),\r
+ *     is this character visible and not a space when printed ?\r
+ * return:\r
+ *     boolean.\r
+ */\r
+static int\r
+printable(int ch) {\r
+       return (ch > 0x20 && ch < 0x7f);\r
+}\r
+\r
+/*\r
+ *     Thinking in noninternationalized USASCII (per the DNS spec),\r
+ *     convert this character to lower case if it's upper case.\r
+ */\r
+static int\r
+mklower(int ch) {\r
+       if (ch >= 0x41 && ch <= 0x5A)\r
+               return (ch + 0x20);\r
+       return (ch);\r
+}\r
+\r
+/*\r
+ * dn_find(domain, msg, dnptrs, lastdnptr)\r
+ *     Search for the counted-label name in an array of compressed names.\r
+ * return:\r
+ *     offset from msg if found, or -1.\r
+ * notes:\r
+ *     dnptrs is the pointer to the first name on the list,\r
+ *     not the pointer to the start of the message.\r
+ */\r
+static int\r
+dn_find(const u_char *domain, const u_char *msg,\r
+       const u_char * const *dnptrs,\r
+       const u_char * const *lastdnptr)\r
+{\r
+       const u_char *dn, *cp, *sp;\r
+       const u_char * const *cpp;\r
+       u_int n;\r
+\r
+       for (cpp = dnptrs; cpp < lastdnptr; cpp++) {\r
+               dn = domain;\r
+               sp = cp = *cpp;\r
+               while ((n = *cp++) != 0) {\r
+                       /*\r
+                        * check for indirection\r
+                        */\r
+                       switch (n & NS_CMPRSFLGS) {\r
+                       case 0:                 /* normal case, n == len */\r
+                               if (n != *dn++)\r
+                                       goto next;\r
+                               for ((void)NULL; n > 0; n--)\r
+                                       if (mklower(*dn++) != mklower(*cp++))\r
+                                               goto next;\r
+                               /* Is next root for both ? */\r
+                               if (*dn == '\0' && *cp == '\0')\r
+                                       return ((int)(sp - msg));\r
+                               if (*dn)\r
+                                       continue;\r
+                               goto next;\r
+\r
+                       case NS_CMPRSFLGS:      /* indirection */\r
+                               cp = msg + (((n & 0x3f) << 8) | *cp);\r
+                               break;\r
+\r
+                       default:        /* illegal type */\r
+                               errno = EMSGSIZE;\r
+                               return (-1);\r
+                       }\r
+               }\r
+ next: ;\r
+       }\r
+       errno = ENOENT;\r
+       return (-1);\r
+}\r
diff --git a/StdLib/BsdSocketLib/ns_netint.c b/StdLib/BsdSocketLib/ns_netint.c
new file mode 100644 (file)
index 0000000..6a3b290
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#ifndef lint\r
+static char rcsid[] = "$Id: ns_netint.c,v 1.1.1.1 2003/11/19 01:51:33 kyu3 Exp $";\r
+#endif\r
+\r
+/* Import. */\r
+\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+\r
+#include <netinet/in.h>\r
+#include <arpa/nameser.h>\r
+\r
+uint16_t\r
+ns_get16(const u_char *src) {\r
+       uint16_t dst;\r
+\r
+       NS_GET16(dst, src);\r
+       return (dst);\r
+}\r
+\r
+uint32_t\r
+ns_get32(const u_char *src) {\r
+       uint32_t dst;\r
+\r
+       NS_GET32(dst, src);\r
+       return (dst);\r
+}\r
+\r
+void\r
+ns_put16(uint16_t src, u_char *dst) {\r
+       NS_PUT16(src, dst);\r
+}\r
+\r
+void\r
+ns_put32(uint32_t src, u_char *dst) {\r
+       NS_PUT32(src, dst);\r
+}\r
diff --git a/StdLib/BsdSocketLib/ns_ntoa.c b/StdLib/BsdSocketLib/ns_ntoa.c
new file mode 100644 (file)
index 0000000..1162b4d
--- /dev/null
@@ -0,0 +1,103 @@
+/*\r
+ * Copyright (c) 1986, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)ns_ntoa.c  8.1 (Berkeley) 6/4/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/param.h>\r
+#include <netns/ns.h>\r
+#include <stdio.h>\r
+\r
+static char *spectHex();\r
+\r
+char *\r
+ns_ntoa(\r
+       struct ns_addr addr\r
+       )\r
+{\r
+       static char obuf[40];\r
+       union { union ns_net net_e; u_long long_e; } net;\r
+       u_short port = htons(addr.x_port);\r
+       register char *cp;\r
+       char *cp2;\r
+       register u_char *up = addr.x_host.c_host;\r
+       u_char *uplim = up + 6;\r
+\r
+       net.net_e = addr.x_net;\r
+       sprintf(obuf, "%lx", (u_long)ntohl(net.long_e));\r
+       cp = spectHex(obuf);\r
+       cp2 = cp + 1;\r
+       while (*up==0 && up < uplim) up++;\r
+       if (up == uplim) {\r
+               if (port) {\r
+                       sprintf(cp, ".0");\r
+                       cp += 2;\r
+               }\r
+       } else {\r
+               sprintf(cp, ".%x", *up++);\r
+               while (up < uplim) {\r
+                       while (*cp) cp++;\r
+                       sprintf(cp, "%02x", *up++);\r
+               }\r
+               cp = spectHex(cp2);\r
+       }\r
+       if (port) {\r
+               sprintf(cp, ".%x", port);\r
+               spectHex(cp + 1);\r
+       }\r
+       return (obuf);\r
+}\r
+\r
+static char *\r
+spectHex(\r
+       char *p0\r
+       )\r
+{\r
+       int ok = 0;\r
+       int nonzero = 0;\r
+       register char *p = p0;\r
+       for (; *p; p++) switch (*p) {\r
+\r
+       case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\r
+               *p += ('A' - 'a');\r
+               /* fall into . . . */\r
+       case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\r
+               ok = 1;\r
+       case '1': case '2': case '3': case '4': case '5':\r
+       case '6': case '7': case '8': case '9':\r
+               nonzero = 1;\r
+       }\r
+       if (nonzero && !ok) { *p++ = 'H'; *p = 0; }\r
+       return (p);\r
+}\r
diff --git a/StdLib/BsdSocketLib/ns_parse.c b/StdLib/BsdSocketLib/ns_parse.c
new file mode 100644 (file)
index 0000000..b050cde
--- /dev/null
@@ -0,0 +1,230 @@
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#ifndef lint\r
+static char rcsid[] = "$Id: ns_parse.c,v 1.1.1.1 2003/11/19 01:51:33 kyu3 Exp $";\r
+#endif\r
+\r
+#include <sys/types.h>\r
+\r
+#include <netinet/in.h>\r
+#include <arpa/nameser.h>\r
+\r
+#include <errno.h>\r
+#include <resolv.h>\r
+#include <string.h>\r
+\r
+/* These need to be in the same order as the nres.h:ns_flag enum. */\r
+struct _ns_flagdata _ns_flagdata[16] = {\r
+       { 0x8000, 15 },         /* qr. */\r
+       { 0x7800, 11 },         /* opcode. */\r
+       { 0x0400, 10 },         /* aa. */\r
+       { 0x0200, 9 },          /* tc. */\r
+       { 0x0100, 8 },          /* rd. */\r
+       { 0x0080, 7 },          /* ra. */\r
+       { 0x0040, 6 },          /* z. */\r
+       { 0x0020, 5 },          /* ad. */\r
+       { 0x0010, 4 },          /* cd. */\r
+       { 0x000f, 0 },          /* rcode. */\r
+       { 0x0000, 0 },          /* expansion (1/6). */\r
+       { 0x0000, 0 },          /* expansion (2/6). */\r
+       { 0x0000, 0 },          /* expansion (3/6). */\r
+       { 0x0000, 0 },          /* expansion (4/6). */\r
+       { 0x0000, 0 },          /* expansion (5/6). */\r
+       { 0x0000, 0 },          /* expansion (6/6). */\r
+};\r
+\r
+static int\r
+skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {\r
+       const u_char *optr = ptr;\r
+\r
+       for ((void)NULL; count > 0; count--) {\r
+               int b, rdlength;\r
+\r
+               b = dn_skipname(ptr, eom);\r
+               if (b < 0)\r
+                       goto emsgsize;\r
+               ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;\r
+               if (section != ns_s_qd) {\r
+                       if (ptr + NS_INT32SZ > eom)\r
+                               goto emsgsize;\r
+                       ptr += NS_INT32SZ/*TTL*/;\r
+                       if (ptr + NS_INT16SZ > eom)\r
+                               goto emsgsize;\r
+                       NS_GET16(rdlength, ptr);\r
+                       ptr += rdlength/*RData*/;\r
+               }\r
+       }\r
+       if (ptr > eom)\r
+               goto emsgsize;\r
+       return ((int)(ptr - optr));\r
+ emsgsize:\r
+       errno = EMSGSIZE;\r
+       return (-1);\r
+}\r
+\r
+int\r
+ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {\r
+       const u_char *eom = msg + msglen;\r
+       int i;\r
+\r
+       memset(handle, 0x5e, sizeof *handle);\r
+       handle->_msg = msg;\r
+       handle->_eom = eom;\r
+       if (msg + NS_INT16SZ > eom)\r
+               goto emsgsize;\r
+       NS_GET16(handle->_id, msg);\r
+       if (msg + NS_INT16SZ > eom)\r
+               goto emsgsize;\r
+       NS_GET16(handle->_flags, msg);\r
+       for (i = 0; i < ns_s_max; i++) {\r
+               if (msg + NS_INT16SZ > eom)\r
+                       goto emsgsize;\r
+               NS_GET16(handle->_counts[i], msg);\r
+       }\r
+       for (i = 0; i < ns_s_max; i++)\r
+               if (handle->_counts[i] == 0)\r
+                       handle->_sections[i] = NULL;\r
+               else {\r
+                       int b = skiprr(msg, eom, (ns_sect)i,\r
+                                      handle->_counts[i]);\r
+\r
+                       if (b < 0)\r
+                               return (-1);\r
+                       handle->_sections[i] = msg;\r
+                       msg += b;\r
+               }\r
+       if (msg != eom)\r
+               goto emsgsize;\r
+       handle->_sect = ns_s_max;\r
+       handle->_rrnum = -1;\r
+       handle->_msg_ptr = NULL;\r
+       return (0);\r
+ emsgsize:\r
+       errno = EMSGSIZE;\r
+       return (-1);\r
+}\r
+\r
+int\r
+ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {\r
+       int b;\r
+\r
+       /* Make section right. */\r
+       if (section < 0 || section >= ns_s_max)\r
+               goto enodev;\r
+       if ((int)section != (int)handle->_sect) {\r
+               handle->_sect = section;\r
+               handle->_rrnum = 0;\r
+               handle->_msg_ptr = handle->_sections[(int)section];\r
+       }\r
+\r
+       /* Make rrnum right. */\r
+       if (rrnum == -1)\r
+               rrnum = handle->_rrnum;\r
+       if (rrnum < 0 || rrnum >= handle->_counts[(int)section])\r
+               goto enodev;\r
+       if (rrnum < handle->_rrnum) {\r
+               handle->_rrnum = 0;\r
+               handle->_msg_ptr = handle->_sections[(int)section];\r
+       }\r
+       \r
+       b = skiprr(handle->_msg, handle->_eom, section,\r
+                  rrnum - handle->_rrnum);\r
+       if (b < 0)\r
+               return (-1);\r
+       handle->_msg_ptr += b;\r
+       handle->_rrnum = rrnum;\r
+\r
+       /* Do the parse. */\r
+       b = dn_expand(handle->_msg, handle->_eom,\r
+                     handle->_msg_ptr, rr->name, NS_MAXDNAME);\r
+       if (b < 0)\r
+               return (-1);\r
+       handle->_msg_ptr += b;\r
+       if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)\r
+               goto emsgsize;\r
+       NS_GET16(rr->type, handle->_msg_ptr);\r
+       if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)\r
+               goto emsgsize;\r
+       NS_GET16(rr->rr_class, handle->_msg_ptr);\r
+       if (section == ns_s_qd) {\r
+               rr->ttl = 0;\r
+               rr->rdlength = 0;\r
+               rr->rdata = NULL;\r
+       } else {\r
+               if (handle->_msg_ptr + NS_INT32SZ > handle->_eom)\r
+                       goto emsgsize;\r
+               NS_GET32(rr->ttl, handle->_msg_ptr);\r
+               if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)\r
+                       goto emsgsize;\r
+               NS_GET16(rr->rdlength, handle->_msg_ptr);\r
+               if (handle->_msg_ptr + rr->rdlength > handle->_eom)\r
+                       goto emsgsize;\r
+               rr->rdata = handle->_msg_ptr;\r
+               handle->_msg_ptr += rr->rdlength;\r
+       }\r
+       handle->_rrnum++;\r
+\r
+       /* All done. */\r
+       return (0);\r
+ enodev:\r
+       errno = ENODEV;\r
+       return (-1);\r
+ emsgsize:\r
+       errno = EMSGSIZE;\r
+       return (-1);\r
+}\r
diff --git a/StdLib/BsdSocketLib/ns_print.c b/StdLib/BsdSocketLib/ns_print.c
new file mode 100644 (file)
index 0000000..83aeeb3
--- /dev/null
@@ -0,0 +1,780 @@
+/*\r
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#ifndef lint\r
+static char rcsid[] = "$Id: ns_print.c,v 1.1.1.1 2003/11/19 01:51:34 kyu3 Exp $";\r
+#endif\r
+\r
+/* Import. */\r
+\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+\r
+#include <netinet/in.h>\r
+#include <arpa/nameser.h>\r
+#include <arpa/inet.h>\r
+\r
+#include <assert.h>\r
+#include <errno.h>\r
+#include <resolv.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+\r
+#define SPRINTF(x) (sprintf x)\r
+\r
+/* Forward. */\r
+\r
+static size_t  prune_origin(const char *name, const char *origin);\r
+static int     charstr(const u_char *rdata, const u_char *edata,\r
+                       char **buf, size_t *buflen);\r
+static int     addname(const u_char *msg, size_t msglen,\r
+                       const u_char **p, const char *origin,\r
+                       char **buf, size_t *buflen);\r
+static void    addlen(size_t len, char **buf, size_t *buflen);\r
+static int     addstr(const char *src, size_t len,\r
+                      char **buf, size_t *buflen);\r
+static int     addtab(size_t len, size_t target, int spaced,\r
+                      char **buf, size_t *buflen);\r
+\r
+/* Macros. */\r
+\r
+#define        T(x) \\r
+       do { \\r
+               if ((ssize_t)(x) < 0) \\r
+                       return (-1); \\r
+       } while (0)\r
+\r
+/* Public. */\r
+\r
+/*\r
+ * int\r
+ * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)\r
+ *     Convert an RR to presentation format.\r
+ * return:\r
+ *     Number of characters written to buf, or -1 (check errno).\r
+ */\r
+int\r
+ns_sprintrr(const ns_msg *handle, const ns_rr *rr,\r
+           const char *name_ctx, const char *origin,\r
+           char *buf, size_t buflen)\r
+{\r
+       int n;\r
+\r
+       n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),\r
+                        ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),\r
+                        ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),\r
+                        name_ctx, origin, buf, buflen);\r
+       return (n);\r
+}\r
+\r
+/*\r
+ * int\r
+ * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,\r
+ *            name_ctx, origin, buf, buflen)\r
+ *     Convert the fields of an RR into presentation format.\r
+ * return:\r
+ *     Number of characters written to buf, or -1 (check errno).\r
+ */\r
+int\r
+ns_sprintrrf(const u_char *msg, size_t msglen,\r
+           const char *name, ns_class class, ns_type type,\r
+           u_long ttl, const u_char *rdata, size_t rdlen,\r
+           const char *name_ctx, const char *origin,\r
+           char *buf, size_t buflen)\r
+{\r
+       const char *obuf = buf;\r
+       const u_char *edata = rdata + rdlen;\r
+       int spaced = 0;\r
+\r
+       const char *comment;\r
+       char tmp[100];\r
+       int x;\r
+       size_t len;\r
+\r
+       static  char base64_key[NS_MD5RSA_MAX_BASE64];\r
+       static  char t[255*3];\r
+\r
+       /*\r
+        * Owner.\r
+        */\r
+       if (name_ctx != NULL && strcasecmp(name_ctx, name) == 0) {\r
+               T(addstr("\t\t\t", 3, &buf, &buflen));\r
+       } else {\r
+               len = prune_origin(name, origin);\r
+               if (len == 0) {\r
+                       T(addstr("@\t\t\t", 4, &buf, &buflen));\r
+               } else {\r
+                       T(addstr(name, len, &buf, &buflen));\r
+                       /* Origin not used and no trailing dot? */\r
+                       if ((!origin || !origin[0] || name[len] == '\0') &&\r
+                           name[len - 1] != '.') {\r
+                               T(addstr(".", 1, &buf, &buflen));\r
+                               len++;\r
+                       }\r
+                       T(spaced = addtab(len, 24, spaced, &buf, &buflen));\r
+               }\r
+       }\r
+\r
+       /*\r
+        * TTL, Class, Type.\r
+        */\r
+       T(x = ns_format_ttl(ttl, buf, buflen));\r
+       addlen(x, &buf, &buflen);\r
+       len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));\r
+       T(addstr(tmp, len, &buf, &buflen));\r
+       T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));\r
+\r
+       /*\r
+        * RData.\r
+        */\r
+       switch (type) {\r
+       case ns_t_a:\r
+               if (rdlen != NS_INADDRSZ)\r
+                       goto formerr;\r
+               (void) inet_ntop(AF_INET, rdata, buf, (socklen_t)buflen);\r
+               addlen(strlen(buf), &buf, &buflen);\r
+               break;\r
+\r
+       case ns_t_cname:\r
+       case ns_t_mb:\r
+       case ns_t_mg:\r
+       case ns_t_mr:\r
+       case ns_t_ns:\r
+       case ns_t_ptr:\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+               break;\r
+\r
+       case ns_t_hinfo:\r
+       case ns_t_isdn:\r
+               /* First word. */\r
+               T(len = charstr(rdata, edata, &buf, &buflen));\r
+               if (len == 0)\r
+                       goto formerr;\r
+               rdata += len;\r
+               T(addstr(" ", 1, &buf, &buflen));\r
+\r
+               /* Second word. */\r
+               T(len = charstr(rdata, edata, &buf, &buflen));\r
+               if (len == 0)\r
+                       goto formerr;\r
+               rdata += len;\r
+               break;\r
+\r
+       case ns_t_soa: {\r
+               u_long t;\r
+\r
+               /* Server name. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+               T(addstr(" ", 1, &buf, &buflen));\r
+\r
+               /* Administrator name. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+               T(addstr(" (\n", 3, &buf, &buflen));\r
+               spaced = 0;\r
+\r
+               if ((edata - rdata) != 5*NS_INT32SZ)\r
+                       goto formerr;\r
+\r
+               /* Serial number. */\r
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;\r
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));\r
+               len = SPRINTF((tmp, "%lu", t));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));\r
+               T(addstr("; serial\n", 9, &buf, &buflen));\r
+               spaced = 0;\r
+\r
+               /* Refresh interval. */\r
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;\r
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));\r
+               T(len = ns_format_ttl(t, buf, buflen));\r
+               addlen(len, &buf, &buflen);\r
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));\r
+               T(addstr("; refresh\n", 10, &buf, &buflen));\r
+               spaced = 0;\r
+\r
+               /* Retry interval. */\r
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;\r
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));\r
+               T(len = ns_format_ttl(t, buf, buflen));\r
+               addlen(len, &buf, &buflen);\r
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));\r
+               T(addstr("; retry\n", 8, &buf, &buflen));\r
+               spaced = 0;\r
+\r
+               /* Expiry. */\r
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;\r
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));\r
+               T(len = ns_format_ttl(t, buf, buflen));\r
+               addlen(len, &buf, &buflen);\r
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));\r
+               T(addstr("; expiry\n", 9, &buf, &buflen));\r
+               spaced = 0;\r
+\r
+               /* Minimum TTL. */\r
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;\r
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));\r
+               T(len = ns_format_ttl(t, buf, buflen));\r
+               addlen(len, &buf, &buflen);\r
+               T(addstr(" )", 2, &buf, &buflen));\r
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));\r
+               T(addstr("; minimum\n", 10, &buf, &buflen));\r
+\r
+               break;\r
+           }\r
+\r
+       case ns_t_mx:\r
+       case ns_t_afsdb:\r
+       case ns_t_rt: {\r
+               u_int t;\r
+\r
+               if (rdlen < NS_INT16SZ)\r
+                       goto formerr;\r
+\r
+               /* Priority. */\r
+               t = ns_get16(rdata);\r
+               rdata += NS_INT16SZ;\r
+               len = SPRINTF((tmp, "%u ", t));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+\r
+               /* Target. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+\r
+               break;\r
+           }\r
+\r
+       case ns_t_px: {\r
+               u_int t;\r
+\r
+               if (rdlen < NS_INT16SZ)\r
+                       goto formerr;\r
+\r
+               /* Priority. */\r
+               t = ns_get16(rdata);\r
+               rdata += NS_INT16SZ;\r
+               len = SPRINTF((tmp, "%u ", t));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+\r
+               /* Name1. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+               T(addstr(" ", 1, &buf, &buflen));\r
+\r
+               /* Name2. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+\r
+               break;\r
+           }\r
+\r
+       case ns_t_x25:\r
+               T(len = charstr(rdata, edata, &buf, &buflen));\r
+               if (len == 0)\r
+                       goto formerr;\r
+               rdata += len;\r
+               break;\r
+\r
+       case ns_t_txt:\r
+               while (rdata < edata) {\r
+                       T(len = charstr(rdata, edata, &buf, &buflen));\r
+                       if (len == 0)\r
+                               goto formerr;\r
+                       rdata += len;\r
+                       if (rdata < edata)\r
+                               T(addstr(" ", 1, &buf, &buflen));\r
+               }\r
+               break;\r
+\r
+       case ns_t_nsap: {\r
+\r
+               (void) inet_nsap_ntoa((int)rdlen, rdata, t);\r
+               T(addstr(t, strlen(t), &buf, &buflen));\r
+               break;\r
+           }\r
+\r
+       case ns_t_aaaa:\r
+               if (rdlen != NS_IN6ADDRSZ)\r
+                       goto formerr;\r
+               (void) inet_ntop(AF_INET6, rdata, buf, (socklen_t)buflen);\r
+               addlen(strlen(buf), &buf, &buflen);\r
+               break;\r
+\r
+       case ns_t_loc: {\r
+               /* XXX protocol format checking? */\r
+               (void) loc_ntoa(rdata, t);\r
+               T(addstr(t, strlen(t), &buf, &buflen));\r
+               break;\r
+           }\r
+\r
+       case ns_t_naptr: {\r
+               u_int order, preference;\r
+\r
+               if (rdlen < 2*NS_INT16SZ)\r
+                       goto formerr;\r
+\r
+               /* Order, Precedence. */\r
+               order = ns_get16(rdata);        rdata += NS_INT16SZ;\r
+               preference = ns_get16(rdata);   rdata += NS_INT16SZ;\r
+               len = SPRINTF((t, "%u %u ", order, preference));\r
+               T(addstr(t, len, &buf, &buflen));\r
+\r
+               /* Flags. */\r
+               T(len = charstr(rdata, edata, &buf, &buflen));\r
+               if (len == 0)\r
+                       goto formerr;\r
+               rdata += len;\r
+               T(addstr(" ", 1, &buf, &buflen));\r
+\r
+               /* Service. */\r
+               T(len = charstr(rdata, edata, &buf, &buflen));\r
+               if (len == 0)\r
+                       goto formerr;\r
+               rdata += len;\r
+               T(addstr(" ", 1, &buf, &buflen));\r
+\r
+               /* Regexp. */\r
+               T(len = charstr(rdata, edata, &buf, &buflen));\r
+               if ((ssize_t)len < 0)\r
+                       return (-1);\r
+               if (len == 0)\r
+                       goto formerr;\r
+               rdata += len;\r
+               T(addstr(" ", 1, &buf, &buflen));\r
+\r
+               /* Server. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+               break;\r
+           }\r
+\r
+       case ns_t_srv: {\r
+               u_int priority, weight, port;\r
+\r
+               if (rdlen < NS_INT16SZ*3)\r
+                       goto formerr;\r
+\r
+               /* Priority, Weight, Port. */\r
+               priority = ns_get16(rdata);  rdata += NS_INT16SZ;\r
+               weight   = ns_get16(rdata);  rdata += NS_INT16SZ;\r
+               port     = ns_get16(rdata);  rdata += NS_INT16SZ;\r
+               len = SPRINTF((t, "%u %u %u ", priority, weight, port));\r
+               T(addstr(t, len, &buf, &buflen));\r
+\r
+               /* Server. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+               break;\r
+           }\r
+\r
+       case ns_t_minfo:\r
+       case ns_t_rp:\r
+               /* Name1. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+               T(addstr(" ", 1, &buf, &buflen));\r
+\r
+               /* Name2. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+\r
+               break;\r
+\r
+       case ns_t_wks: {\r
+               int n, lcnt;\r
+\r
+               if (rdlen < NS_INT32SZ + 1)\r
+                       goto formerr;\r
+\r
+               /* Address. */\r
+               (void) inet_ntop(AF_INET, rdata, buf, (socklen_t)buflen);\r
+               addlen(strlen(buf), &buf, &buflen);\r
+               rdata += NS_INADDRSZ;\r
+\r
+               /* Protocol. */\r
+               len = SPRINTF((tmp, " %u ( ", *rdata));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+               rdata += NS_INT8SZ;\r
+\r
+               /* Bit map. */\r
+               n = 0;\r
+               lcnt = 0;\r
+               while (rdata < edata) {\r
+                       u_int c = *rdata++;\r
+                       do {\r
+                               if (c & 0200) {\r
+                                       if (lcnt == 0) {\r
+                                               T(addstr("\n\t\t\t\t", 5,\r
+                                                        &buf, &buflen));\r
+                                               lcnt = 10;\r
+                                               spaced = 0;\r
+                                       }\r
+                                       len = SPRINTF((tmp, "%d ", n));\r
+                                       T(addstr(tmp, len, &buf, &buflen));\r
+                                       lcnt--;\r
+                               }\r
+                               c <<= 1;\r
+                       } while (++n & 07);\r
+               }\r
+               T(addstr(")", 1, &buf, &buflen));\r
+\r
+               break;\r
+           }\r
+\r
+       case ns_t_key: {\r
+               u_int keyflags, protocol, algorithm;\r
+               const char *leader;\r
+               int n;\r
+\r
+               if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)\r
+                       goto formerr;\r
+\r
+               /* Key flags, Protocol, Algorithm. */\r
+               keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;\r
+               protocol = *rdata++;\r
+               algorithm = *rdata++;\r
+               len = SPRINTF((tmp, "0x%04x %u %u",\r
+                              keyflags, protocol, algorithm));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+\r
+               /* Public key data. */\r
+               len = b64_ntop(rdata, edata - rdata,\r
+                              base64_key, sizeof base64_key);\r
+               if ((ssize_t)len < 0)\r
+                       goto formerr;\r
+               if (len > 15) {\r
+                       T(addstr(" (", 2, &buf, &buflen));\r
+                       leader = "\n\t\t";\r
+                       spaced = 0;\r
+               } else\r
+                       leader = " ";\r
+               for (n = 0; n < (int)len; n += 48) {\r
+                       T(addstr(leader, strlen(leader), &buf, &buflen));\r
+                       T(addstr(base64_key + n, MIN(len - n, 48),\r
+                                &buf, &buflen));\r
+               }\r
+               if (len > 15)\r
+                       T(addstr(" )", 2, &buf, &buflen));\r
+\r
+               break;\r
+           }\r
+\r
+       case ns_t_sig: {\r
+               u_int type, algorithm, labels, footprint;\r
+               const char *leader;\r
+               u_long t;\r
+               int n;\r
+\r
+               if (rdlen < 22)\r
+                       goto formerr;\r
+\r
+               /* Type covered, Algorithm, Label count, Original TTL. */\r
+               type = ns_get16(rdata);  rdata += NS_INT16SZ;\r
+               algorithm = *rdata++;\r
+               labels = *rdata++;\r
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;\r
+               len = SPRINTF((tmp, " %s %d %lu ",\r
+                              p_type((int)type), algorithm, t));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+               if (labels != (u_int)dn_count_labels(name))\r
+                       goto formerr;\r
+\r
+               /* Signature expiry. */\r
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;\r
+               len = SPRINTF((tmp, "%s ", p_secstodate(t)));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+\r
+               /* Time signed. */\r
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;\r
+               len = SPRINTF((tmp, "%s ", p_secstodate(t)));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+\r
+               /* Signature Footprint. */\r
+               footprint = ns_get16(rdata);  rdata += NS_INT16SZ;\r
+               len = SPRINTF((tmp, "%u ", footprint));\r
+               T(addstr(tmp, len, &buf, &buflen));\r
+\r
+               /* Signer's name. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+\r
+               /* Signature. */\r
+               len = b64_ntop(rdata, edata - rdata,\r
+                              base64_key, sizeof base64_key);\r
+               if (len > 15) {\r
+                       T(addstr(" (", 2, &buf, &buflen));\r
+                       leader = "\n\t\t";\r
+                       spaced = 0;\r
+               } else\r
+                       leader = " ";\r
+               if ((ssize_t)len < 0)\r
+                       goto formerr;\r
+               for (n = 0; n < (int)len; n += 48) {\r
+                       T(addstr(leader, strlen(leader), &buf, &buflen));\r
+                       T(addstr(base64_key + n, MIN(len - n, 48),\r
+                                &buf, &buflen));\r
+               }\r
+               if (len > 15)\r
+                       T(addstr(" )", 2, &buf, &buflen));\r
+\r
+               break;\r
+           }\r
+\r
+       case ns_t_nxt: {\r
+               int n, c;\r
+\r
+               /* Next domain name. */\r
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));\r
+\r
+               /* Type bit map. */\r
+               n = (int)(edata - rdata);\r
+               for (c = 0; c < n*8; c++)\r
+                       if (NS_NXT_BIT_ISSET(c, rdata)) {\r
+                               len = SPRINTF((tmp, " %s", p_type(c)));\r
+                               T(addstr(tmp, len, &buf, &buflen));\r
+                       }\r
+               break;\r
+           }\r
+\r
+       default:\r
+               comment = "unknown RR type";\r
+               goto hexify;\r
+       }\r
+       return ((int)(buf - obuf));\r
+ formerr:\r
+       comment = "RR format error";\r
+ hexify: {\r
+       int n, m;\r
+       char *p;\r
+\r
+       len = SPRINTF((tmp, "\\#(\t\t; %s", comment));\r
+       T(addstr(tmp, len, &buf, &buflen));\r
+       while (rdata < edata) {\r
+               p = tmp;\r
+               p += SPRINTF((p, "\n\t"));\r
+               spaced = 0;\r
+               n = MIN(16, (int)(edata - rdata));\r
+               for (m = 0; m < n; m++)\r
+                       p += SPRINTF((p, "%02x ", rdata[m]));\r
+               T(addstr(tmp, (u_int)(p - tmp), &buf, &buflen));\r
+               if (n < 16) {\r
+                       T(addstr(")", 1, &buf, &buflen));\r
+                       T(addtab((u_int)(p - tmp) + 1, 48, spaced, &buf, &buflen));\r
+               }\r
+               p = tmp;\r
+               p += SPRINTF((p, "; "));\r
+               for (m = 0; m < n; m++)\r
+                       *p++ = (isascii(rdata[m]) && isprint(rdata[m]))\r
+                               ? rdata[m]\r
+                               : '.';\r
+               T(addstr(tmp, (u_int)(p - tmp), &buf, &buflen));\r
+               rdata += n;\r
+       }\r
+       return ((int)(buf - obuf));\r
+    }\r
+}\r
+\r
+/* Private. */\r
+\r
+/*\r
+ * size_t\r
+ * prune_origin(name, origin)\r
+ *     Find out if the name is at or under the current origin.\r
+ * return:\r
+ *     Number of characters in name before start of origin,\r
+ *     or length of name if origin does not match.\r
+ * notes:\r
+ *     This function should share code with samedomain().\r
+ */\r
+static size_t\r
+prune_origin(const char *name, const char *origin) {\r
+       const char *oname = name;\r
+\r
+       while (*name != '\0') {\r
+               if (origin != NULL && strcasecmp(name, origin) == 0)\r
+                       return ((size_t)(name - oname) - (name > oname));\r
+               while (*name != '\0') {\r
+                       if (*name == '\\') {\r
+                               name++;\r
+                               /* XXX need to handle \nnn form. */\r
+                               if (*name == '\0')\r
+                                       break;\r
+                       } else if (*name == '.') {\r
+                               name++;\r
+                               break;\r
+                       }\r
+                       name++;\r
+               }\r
+       }\r
+       return ((size_t)(name - oname));\r
+}\r
+\r
+/*\r
+ * int\r
+ * charstr(rdata, edata, buf, buflen)\r
+ *     Format a <character-string> into the presentation buffer.\r
+ * return:\r
+ *     Number of rdata octets consumed\r
+ *     0 for protocol format error\r
+ *     -1 for output buffer error\r
+ * side effects:\r
+ *     buffer is advanced on success.\r
+ */\r
+static int\r
+charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {\r
+       const u_char *odata = rdata;\r
+       size_t save_buflen = *buflen;\r
+       char *save_buf = *buf;\r
+\r
+       if (addstr("\"", 1, buf, buflen) < 0)\r
+               goto enospc;\r
+       if (rdata < edata) {\r
+               int n = *rdata;\r
+\r
+               if (rdata + 1 + n <= edata) {\r
+                       rdata++;\r
+                       while (n-- > 0) {\r
+                               if (strchr("\n\"\\", *rdata) != NULL)\r
+                                       if (addstr("\\", 1, buf, buflen) < 0)\r
+                                               goto enospc;\r
+                               if (addstr((const char *)rdata, 1,\r
+                                          buf, buflen) < 0)\r
+                                       goto enospc;\r
+                               rdata++;\r
+                       }\r
+               }\r
+       }\r
+       if (addstr("\"", 1, buf, buflen) < 0)\r
+               goto enospc;\r
+       return ((int)(rdata - odata));\r
+ enospc:\r
+       errno = ENOSPC;\r
+       *buf = save_buf;\r
+       *buflen = save_buflen;\r
+       return (-1);\r
+}\r
+\r
+static int\r
+addname(const u_char *msg, size_t msglen,\r
+       const u_char **pp, const char *origin,\r
+       char **buf, size_t *buflen)\r
+{\r
+       size_t newlen, save_buflen = *buflen;\r
+       char *save_buf = *buf;\r
+       int n;\r
+\r
+       n = dn_expand(msg, msg + msglen, *pp, *buf, (int)(*buflen));\r
+       if (n < 0)\r
+               goto enospc;    /* Guess. */\r
+       newlen = prune_origin(*buf, origin);\r
+       if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') &&\r
+           (newlen == 0 || (*buf)[newlen - 1] != '.')) {\r
+               /* No trailing dot. */\r
+               if (newlen + 2 > *buflen)\r
+                       goto enospc;    /* No room for ".\0". */\r
+               (*buf)[newlen++] = '.';\r
+               (*buf)[newlen] = '\0';\r
+       }\r
+       if (newlen == 0) {\r
+               /* Use "@" instead of name. */\r
+               if (newlen + 2 > *buflen)\r
+                       goto enospc;        /* No room for "@\0". */\r
+               (*buf)[newlen++] = '@';\r
+               (*buf)[newlen] = '\0';\r
+       }\r
+       *pp += n;\r
+       addlen(newlen, buf, buflen);\r
+       **buf = '\0';\r
+       return ((int)newlen);\r
+ enospc:\r
+       errno = ENOSPC;\r
+       *buf = save_buf;\r
+       *buflen = save_buflen;\r
+       return (-1);\r
+}\r
+\r
+static void\r
+addlen(size_t len, char **buf, size_t *buflen) {\r
+       assert(len <= *buflen);\r
+       *buf += len;\r
+       *buflen -= len;\r
+}\r
+\r
+static int\r
+addstr(const char *src, size_t len, char **buf, size_t *buflen) {\r
+       if (len > *buflen) {\r
+               errno = ENOSPC;\r
+               return (-1);\r
+       }\r
+       memcpy(*buf, src, len);\r
+       addlen(len, buf, buflen);\r
+       **buf = '\0';\r
+       return (0);\r
+}\r
+\r
+static int\r
+addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {\r
+       size_t save_buflen = *buflen;\r
+       char *save_buf = *buf;\r
+       int t;\r
+\r
+       if (spaced || len >= target - 1) {\r
+               T(addstr("  ", 2, buf, buflen));\r
+               spaced = 1;\r
+       } else {\r
+               for (t = (int)(target - len - 1) / 8; t >= 0; t--)\r
+                       if (addstr("\t", 1, buf, buflen) < 0) {\r
+                               *buflen = save_buflen;\r
+                               *buf = save_buf;\r
+                               return (-1);\r
+                       }\r
+               spaced = 0;\r
+       }\r
+       return (spaced);\r
+}\r
diff --git a/StdLib/BsdSocketLib/ns_ttl.c b/StdLib/BsdSocketLib/ns_ttl.c
new file mode 100644 (file)
index 0000000..a5a5744
--- /dev/null
@@ -0,0 +1,191 @@
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ * \r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ */\r
+\r
+#ifndef lint\r
+static char rcsid[] = "$Id: ns_ttl.c,v 1.1.1.1 2003/11/19 01:51:34 kyu3 Exp $";\r
+#endif\r
+\r
+/* Import. */\r
+\r
+#include <arpa/nameser.h>\r
+\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#define SPRINTF(x) ((size_t)sprintf x)\r
+\r
+/* Forward. */\r
+\r
+static int     fmt1(int t, char s, char **buf, size_t *buflen);\r
+\r
+/* Macros. */\r
+\r
+#define T(x) if ((x) < 0) return (-1); else (void)NULL\r
+\r
+/* Public. */\r
+\r
+int\r
+ns_format_ttl(u_long src, char *dst, size_t dstlen) {\r
+       char *odst = dst;\r
+       int secs, mins, hours, days, weeks, x;\r
+       char *p;\r
+\r
+       secs =  (int)(src % 60);  src /= 60;\r
+       mins =  (int)(src % 60);  src /= 60;\r
+       hours = (int)(src % 24);  src /= 24;\r
+       days =  (int)(src % 7);   src /= 7;\r
+       weeks = (int)src;         src = 0;\r
+\r
+       x = 0;\r
+       if (weeks) {\r
+               T(fmt1(weeks, 'W', &dst, &dstlen));\r
+               x++;\r
+       }\r
+       if (days) {\r
+               T(fmt1(days, 'D', &dst, &dstlen));\r
+               x++;\r
+       }\r
+       if (hours) {\r
+               T(fmt1(hours, 'H', &dst, &dstlen));\r
+               x++;\r
+       }\r
+       if (mins) {\r
+               T(fmt1(mins, 'M', &dst, &dstlen));\r
+               x++;\r
+       }\r
+       if (secs || !(weeks || days || hours || mins)) {\r
+               T(fmt1(secs, 'S', &dst, &dstlen));\r
+               x++;\r
+       }\r
+\r
+       if (x > 1) {\r
+               int ch;\r
+\r
+               for (p = odst; (ch = *p) != '\0'; p++)\r
+                       if (isascii(ch) && isupper(ch))\r
+                               *p = (char)( tolower(ch));\r
+       }\r
+\r
+       return ((int)(dst - odst));\r
+}\r
+\r
+int\r
+ns_parse_ttl(const char *src, u_long *dst) {\r
+       u_long ttl, tmp;\r
+       int ch, digits, dirty;\r
+\r
+       ttl = 0;\r
+       tmp = 0;\r
+       digits = 0;\r
+       dirty = 0;\r
+       while ((ch = *src++) != '\0') {\r
+               if (!isascii(ch) || !isprint(ch))\r
+                       goto einval;\r
+               if (isdigit(ch)) {\r
+                       tmp *= 10;\r
+                       tmp += (ch - '0');\r
+                       digits++;\r
+                       continue;\r
+               }\r
+               if (digits == 0)\r
+                       goto einval;\r
+               if (islower(ch))\r
+                       ch = toupper(ch);\r
+               switch (ch) {\r
+               case 'W':  tmp *= 7;\r
+               case 'D':  tmp *= 24;\r
+               case 'H':  tmp *= 60;\r
+               case 'M':  tmp *= 60;\r
+               case 'S':  break;\r
+               default:   goto einval;\r
+               }\r
+               ttl += tmp;\r
+               tmp = 0;\r
+               digits = 0;\r
+               dirty = 1;\r
+       }\r
+       if (digits > 0) {\r
+               if (dirty)\r
+                       goto einval;\r
+               else\r
+                       ttl += tmp;\r
+       }\r
+       *dst = ttl;\r
+       return (0);\r
+\r
+ einval:\r
+       errno = EINVAL;\r
+       return (-1);\r
+}\r
+\r
+/* Private. */\r
+\r
+static int\r
+fmt1(int t, char s, char **buf, size_t *buflen) {\r
+       char tmp[50];\r
+       size_t len;\r
+\r
+       len = SPRINTF((tmp, "%d%c", t, s));\r
+       if (len + 1 > *buflen)\r
+               return (-1);\r
+       strcpy(*buf, tmp);\r
+       *buf += len;\r
+       *buflen -= len;\r
+       return (0);\r
+}\r
diff --git a/StdLib/BsdSocketLib/nsap_addr.c b/StdLib/BsdSocketLib/nsap_addr.c
new file mode 100644 (file)
index 0000000..957c97f
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char rcsid[] = "$Id: nsap_addr.c,v 1.1.1.1 2003/11/19 01:51:31 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+#include <ctype.h>\r
+#include <resolv.h>\r
+\r
+static char\r
+xtob(\r
+       register int c\r
+       )\r
+{\r
+       return (char)(c - (((c >= '0') && (c <= '9')) ? '0' : '7'));\r
+}\r
+\r
+u_int\r
+inet_nsap_addr(\r
+       const char *ascii,\r
+       u_char *binary,\r
+       int maxlen\r
+       )\r
+{\r
+       u_char c, nib;\r
+       u_int len = 0;\r
+\r
+       while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {\r
+               if (c == '.' || c == '+' || c == '/')\r
+                       continue;\r
+               if (!isascii(c))\r
+                       return (0);\r
+               if (islower(c))\r
+                       c = (u_char)( toupper(c));\r
+               if (isxdigit(c)) {\r
+                       nib = xtob(c);\r
+                       c = *ascii++;\r
+                       if (c != '\0') {\r
+                               c = (u_char)( toupper(c));\r
+                               if (isxdigit(c)) {\r
+                                       *binary++ = (nib << 4) | xtob(c);\r
+                                       len++;\r
+                               } else\r
+                                       return (0);\r
+                       }\r
+                       else\r
+                               return (0);\r
+               }\r
+               else\r
+                       return (0);\r
+       }\r
+       return (len);\r
+}\r
+\r
+char *\r
+inet_nsap_ntoa(\r
+       int binlen,\r
+       register const u_char *binary,\r
+       register char *ascii\r
+       )\r
+{\r
+       register int nib;\r
+       int i;\r
+       static char tmpbuf[255*3];\r
+       char *start;\r
+\r
+       if (ascii)\r
+               start = ascii;\r
+       else {\r
+               ascii = tmpbuf;\r
+               start = tmpbuf;\r
+       }\r
+\r
+       if (binlen > 255)\r
+               binlen = 255;\r
+\r
+       for (i = 0; i < binlen; i++) {\r
+               nib = *binary >> 4;\r
+               *ascii++ = (char)( nib + (nib < 10 ? '0' : '7'));\r
+               nib = *binary++ & 0x0f;\r
+               *ascii++ = (char)( nib + (nib < 10 ? '0' : '7'));\r
+               if (((i % 2) == 0 && (i + 1) < binlen))\r
+                       *ascii++ = '.';\r
+       }\r
+       *ascii = '\0';\r
+       return (start);\r
+}\r
diff --git a/StdLib/BsdSocketLib/poll.c b/StdLib/BsdSocketLib/poll.c
new file mode 100644 (file)
index 0000000..fdf50e8
--- /dev/null
@@ -0,0 +1,57 @@
+/** @file\r
+  Implement the poll API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Poll the socket for activity\r
+\r
+  @param [in] pDescriptor Descriptor address for the file\r
+\r
+  @param [in] Events      Mask of events to detect\r
+\r
+  @returns    Detected events for the socket\r
+\r
+ **/\r
+short\r
+BslSocketPoll (\r
+  IN struct __filedes * pDescriptor,\r
+  IN short Events\r
+  )\r
+{\r
+  short DetectedEvents;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Locate the socket protocol\r
+  //\r
+  DetectedEvents = 0;\r
+  pSocketProtocol = BslValidateSocketFd ( pDescriptor, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Poll the socket\r
+    //\r
+    Status = pSocketProtocol->pfnPoll ( pSocketProtocol,\r
+                                        Events,\r
+                                        &DetectedEvents,\r
+                                        &errno );\r
+  }\r
+\r
+  //\r
+  //  Return the detected events\r
+  //\r
+  return DetectedEvents;\r
+}\r
diff --git a/StdLib/BsdSocketLib/read.c b/StdLib/BsdSocketLib/read.c
new file mode 100644 (file)
index 0000000..eb72f5c
--- /dev/null
@@ -0,0 +1,53 @@
+/** @file\r
+  Implement the read API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Read support routine for sockets\r
+\r
+  @param [in] pDescriptor   Descriptor address for the file\r
+  @param [in] pOffset       File offset\r
+  @param [in] LengthInBytes Number of bytes to read\r
+  @param [in] pBuffer       Address of the buffer to receive the data\r
+\r
+  @returns  The number of bytes read or -1 if an error occurs.\r
+\r
+**/\r
+ssize_t\r
+BslSocketRead (\r
+  struct __filedes *pDescriptor,\r
+  off_t * pOffset,\r
+  size_t LengthInBytes,\r
+  void * pBuffer\r
+  )\r
+{\r
+  ssize_t BytesRead;\r
+\r
+  //\r
+  //  Receive the data from the remote system\r
+  //\r
+  BytesRead = recvfrom ( pDescriptor->MyFD,\r
+                         pBuffer,\r
+                         LengthInBytes,\r
+                         0,\r
+                         NULL,\r
+                         NULL );\r
+\r
+  //\r
+  //  Return the number of bytes read\r
+  //\r
+  return BytesRead;\r
+}\r
diff --git a/StdLib/BsdSocketLib/recv.c b/StdLib/BsdSocketLib/recv.c
new file mode 100644 (file)
index 0000000..735e1db
--- /dev/null
@@ -0,0 +1,63 @@
+/** @file\r
+  Implement the recv API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Receive data from a network connection.\r
+\r
+  The ::recv routine waits for receive data from a remote network\r
+  connection.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] buffer    Address of a buffer to receive the data.\r
+  \r
+  @param [in] length    Length of the buffer in bytes.\r
+\r
+  @param [in] flags     Message control flags\r
+\r
+  @returns    ::recv returns the number of valid bytes in the buffer,\r
+              zero if no data was received, and -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+ssize_t\r
+recv (\r
+  int s,\r
+  void * buffer,\r
+  size_t length,\r
+  int flags\r
+  )\r
+{\r
+  ssize_t BytesRead;\r
+  \r
+  //\r
+  //  Receive the data from the remote system\r
+  //\r
+  BytesRead = recvfrom ( s,\r
+                         buffer,\r
+                         length,\r
+                         flags,\r
+                         NULL,\r
+                         NULL );\r
+\r
+  //\r
+  //  Return the number of bytes read\r
+  //\r
+  return BytesRead;\r
+}\r
diff --git a/StdLib/BsdSocketLib/recvfrom.c b/StdLib/BsdSocketLib/recvfrom.c
new file mode 100644 (file)
index 0000000..a8d1ab5
--- /dev/null
@@ -0,0 +1,197 @@
+/** @file\r
+  Implement the recvfrom API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Receive data from a network connection and return the remote system's address.\r
+\r
+  The ::recvfrom routine waits for receive data from a remote network\r
+  connection.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] buffer    Address of a buffer to receive the data.\r
+  \r
+  @param [in] length    Length of the buffer in bytes.\r
+\r
+  @param [in] flags     Message control flags\r
+\r
+  @param [out] address  Network address to receive the remote system address\r
+\r
+  @param [in] address_len Length of the remote network address structure\r
+\r
+  @returns    ::recvfrom returns the number of valid bytes in the buffer,\r
+              zero if no data was received, and -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+ssize_t\r
+recvfrom (\r
+  int s,\r
+  void * buffer,\r
+  size_t length,\r
+  int flags,\r
+  struct sockaddr * address,\r
+  socklen_t * address_len\r
+  )\r
+{\r
+  socklen_t ByteCount;\r
+  ssize_t LengthInBytes;\r
+  UINT8 * pData;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+  struct timeval TimeVal;\r
+  EFI_EVENT pTimer;\r
+  UINT64 Timeout;\r
+  ssize_t TotalBytes;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  LengthInBytes = -1;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Receive the data from the socket\r
+    //\r
+    Status = pSocketProtocol->pfnReceive ( pSocketProtocol,\r
+                                           flags,\r
+                                           length,\r
+                                           buffer,\r
+                                           (size_t *)&LengthInBytes,\r
+                                           address,\r
+                                           address_len,\r
+                                           &errno );\r
+    if ( EFI_ERROR ( Status )) {\r
+      LengthInBytes = -1;\r
+      if ( EAGAIN == errno ) {\r
+        //\r
+        //  Get the timeout\r
+        //\r
+        ByteCount = sizeof ( TimeVal );\r
+        LengthInBytes = getsockopt ( s,\r
+                                     SOL_SOCKET,\r
+                                     SO_RCVTIMEO,\r
+                                     &TimeVal,\r
+                                     &ByteCount );\r
+        if ( 0 == LengthInBytes ) {\r
+          //\r
+          //  Compute the timeout\r
+          //\r
+          Timeout = TimeVal.tv_sec;\r
+          Timeout *= 1000 * 1000;\r
+          Timeout += TimeVal.tv_usec;\r
+          Timeout *= 10;\r
+\r
+          //\r
+          //  The timer is only necessary if a timeout is running\r
+          //\r
+          LengthInBytes = -1;\r
+          Status = EFI_SUCCESS;\r
+          pTimer = NULL;\r
+          if ( 0 != Timeout ) {\r
+            Status = gBS->CreateEvent ( EVT_TIMER,\r
+                                        TPL_NOTIFY,\r
+                                        NULL,\r
+                                        NULL,\r
+                                        &pTimer );\r
+          }\r
+          if ( !EFI_ERROR ( Status )) {\r
+            //\r
+            //  Start the timer\r
+            //\r
+            if ( NULL != pTimer ) {\r
+              Status = gBS->SetTimer ( pTimer,\r
+                                       TimerRelative,\r
+                                       Timeout );\r
+            }\r
+            if ( !EFI_ERROR ( Status )) {\r
+              //\r
+              //  Loop until data is received or the timeout\r
+              //  expires\r
+              //\r
+              TotalBytes = 0;\r
+              pData = (UINT8 *)buffer;\r
+              do {\r
+                //\r
+                //  Determine if the timeout expired\r
+                //\r
+                if ( NULL != pTimer ) {\r
+                  Status = gBS->CheckEvent ( pTimer );\r
+                  if ( EFI_SUCCESS == Status ) {\r
+                    errno = ETIMEDOUT;\r
+                    if ( 0 == TotalBytes ) {\r
+                      TotalBytes = -1;\r
+                    }\r
+                    break;\r
+                  }\r
+                }\r
+\r
+                //\r
+                //  Attempt to receive some data\r
+                //\r
+                Status = pSocketProtocol->pfnReceive ( pSocketProtocol,\r
+                                                       flags,\r
+                                                       length,\r
+                                                       pData,\r
+                                                       (size_t *)&LengthInBytes,\r
+                                                       address,\r
+                                                       address_len,\r
+                                                       &errno );\r
+                if ( !EFI_ERROR ( Status )) {\r
+                  //\r
+                  //  Account for the data received\r
+                  //\r
+                  TotalBytes += LengthInBytes;\r
+                  pData += LengthInBytes;\r
+                  length -= LengthInBytes;\r
+                }\r
+              } while ( EFI_NOT_READY == Status );\r
+              LengthInBytes = TotalBytes;\r
+\r
+              //\r
+              //  Stop the timer\r
+              //\r
+              if ( NULL != pTimer ) {\r
+                gBS->SetTimer ( pTimer,\r
+                                TimerCancel,\r
+                                0 );\r
+              }\r
+            }\r
+\r
+            //\r
+            //  Release the timer\r
+            //\r
+            if ( NULL != pTimer ) {\r
+              gBS->CloseEvent ( pTimer );\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the receive data length, -1 for errors\r
+  //\r
+  return LengthInBytes;\r
+}\r
diff --git a/StdLib/BsdSocketLib/res_comp.c b/StdLib/BsdSocketLib/res_comp.c
new file mode 100644 (file)
index 0000000..cddda3e
--- /dev/null
@@ -0,0 +1,272 @@
+/*\r
+ * Copyright (c) 1985, 1993\r
+ *    The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ *\r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)res_comp.c  8.1 (Berkeley) 6/4/93";\r
+static char orig_rcsid[] = "From: Id: res_comp.c,v 8.11 1997/05/21 19:31:04 halley Exp $";\r
+static char rcsid[] = "$Id: res_comp.c,v 1.1.1.1 2003/11/19 01:51:35 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <netinet/in.h>\r
+#include <arpa/nameser.h>\r
+#include <ctype.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+\r
+#define BIND_4_COMPAT\r
+\r
+/*\r
+ * Expand compressed domain name 'comp_dn' to full domain name.\r
+ * 'msg' is a pointer to the begining of the message,\r
+ * 'eomorig' points to the first location after the message,\r
+ * 'exp_dn' is a pointer to a buffer of size 'length' for the result.\r
+ * Return size of compressed name or -1 if there was an error.\r
+ */\r
+int\r
+dn_expand(const u_char *msg, const u_char *eom, const u_char *src,\r
+      char *dst, int dstsiz)\r
+{\r
+    int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);\r
+\r
+    if (n > 0 && dst[0] == '.')\r
+        dst[0] = '\0';\r
+    return (n);\r
+}\r
+\r
+/*\r
+ * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.\r
+ * Return the size of the compressed name or -1.\r
+ * 'length' is the size of the array pointed to by 'comp_dn'.\r
+ */\r
+int\r
+dn_comp(const char *src, u_char *dst, int dstsiz,\r
+    u_char **dnptrs, u_char **lastdnptr)\r
+{\r
+    return (ns_name_compress(src, dst, (size_t)dstsiz,\r
+                 (const u_char **)dnptrs,\r
+                 (const u_char **)lastdnptr));\r
+}\r
+\r
+/*\r
+ * Skip over a compressed domain name. Return the size or -1.\r
+ */\r
+int\r
+dn_skipname(const u_char *ptr, const u_char *eom) {\r
+    const u_char *saveptr = ptr;\r
+\r
+    if (ns_name_skip(&ptr, eom) == -1)\r
+        return (-1);\r
+    return ((int)(ptr - saveptr));\r
+}\r
+\r
+/*\r
+ * Verify that a domain name uses an acceptable character set.\r
+ */\r
+\r
+/*\r
+ * Note the conspicuous absence of ctype macros in these definitions.  On\r
+ * non-ASCII hosts, we can't depend on string literals or ctype macros to\r
+ * tell us anything about network-format data.  The rest of the BIND system\r
+ * is not careful about this, but for some reason, we're doing it right here.\r
+ */\r
+#define PERIOD 0x2e\r
+#define hyphenchar(c) ((c) == 0x2d)\r
+#define bslashchar(c) ((c) == 0x5c)\r
+#define periodchar(c) ((c) == PERIOD)\r
+#define asterchar(c) ((c) == 0x2a)\r
+#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \\r
+           || ((c) >= 0x61 && (c) <= 0x7a))\r
+#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)\r
+\r
+#define borderchar(c) (alphachar(c) || digitchar(c))\r
+#define middlechar(c) (borderchar(c) || hyphenchar(c))\r
+#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)\r
+\r
+int\r
+res_hnok(\r
+    const char *dn\r
+    )\r
+{\r
+    int ppch = '\0', pch = PERIOD, ch = *dn++;\r
+\r
+    while (ch != '\0') {\r
+        int nch = *dn++;\r
+\r
+        if (periodchar(ch)) {\r
+            (void)NULL;\r
+        } else if (periodchar(pch)) {\r
+            if (!borderchar(ch))\r
+                return (0);\r
+        } else if (periodchar(nch) || nch == '\0') {\r
+            if (!borderchar(ch))\r
+                return (0);\r
+        } else {\r
+            if (!middlechar(ch))\r
+                return (0);\r
+        }\r
+        ppch = pch, pch = ch, ch = nch;\r
+    }\r
+    return (1);\r
+}\r
+\r
+/*\r
+ * hostname-like (A, MX, WKS) owners can have "*" as their first label\r
+ * but must otherwise be as a host name.\r
+ */\r
+int\r
+res_ownok(\r
+    const char *dn\r
+    )\r
+{\r
+    if (asterchar(dn[0])) {\r
+        if (periodchar(dn[1]))\r
+            return (res_hnok(dn+2));\r
+        if (dn[1] == '\0')\r
+            return (1);\r
+    }\r
+    return (res_hnok(dn));\r
+}\r
+\r
+/*\r
+ * SOA RNAMEs and RP RNAMEs can have any printable character in their first\r
+ * label, but the rest of the name has to look like a host name.\r
+ */\r
+int\r
+res_mailok(\r
+    const char *dn\r
+    )\r
+{\r
+    int ch, escaped = 0;\r
+\r
+    /* "." is a valid missing representation */\r
+    if (*dn == '\0')\r
+        return (1);\r
+\r
+    /* otherwise <label>.<hostname> */\r
+    while ((ch = *dn++) != '\0') {\r
+        if (!domainchar(ch))\r
+            return (0);\r
+        if (!escaped && periodchar(ch))\r
+            break;\r
+        if (escaped)\r
+            escaped = 0;\r
+        else if (bslashchar(ch))\r
+            escaped = 1;\r
+    }\r
+    if (periodchar(ch))\r
+        return (res_hnok(dn));\r
+    return (0);\r
+}\r
+\r
+/*\r
+ * This function is quite liberal, since RFC 1034's character sets are only\r
+ * recommendations.\r
+ */\r
+int\r
+res_dnok(\r
+    const char *dn\r
+    )\r
+{\r
+    int ch;\r
+\r
+    while ((ch = *dn++) != '\0')\r
+        if (!domainchar(ch))\r
+            return (0);\r
+    return (1);\r
+}\r
+\r
+#ifdef BIND_4_COMPAT\r
+/*\r
+ * This module must export the following externally-visible symbols:\r
+ *    ___putlong\r
+ *    ___putshort\r
+ *    __getlong\r
+ *    __getshort\r
+ * Note that one _ comes from C and the others come from us.\r
+ */\r
+void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }\r
+void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }\r
+u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }\r
+u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }\r
+#endif /*BIND_4_COMPAT*/\r
diff --git a/StdLib/BsdSocketLib/res_config.h b/StdLib/BsdSocketLib/res_config.h
new file mode 100644 (file)
index 0000000..4f4afdf
--- /dev/null
@@ -0,0 +1,8 @@
+#define DEBUG   1   /* enable debugging code (needed for dig) */\r
+#define RESOLVSORT  /* allow sorting of addresses in gethostbyname */\r
+#define RFC1535     /* comply with RFC1535 (STRONGLY reccomended by vixie)*/\r
+#undef  USELOOPBACK /* res_init() bind to localhost */\r
+#undef  SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT  */\r
+#define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */\r
+#define CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */\r
+#define BIND_UPDATE 1   /* update support */\r
diff --git a/StdLib/BsdSocketLib/res_data.c b/StdLib/BsdSocketLib/res_data.c
new file mode 100644 (file)
index 0000000..8831653
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+ * Copyright (c) 1995,1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char rcsid[] = "$Id: res_data.c,v 1.1.1.1 2003/11/19 01:51:35 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <sys/time.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+#include <ctype.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+\r
+#include "res_config.h"\r
+\r
+const char *_res_opcodes[] = {\r
+    "QUERY",\r
+    "IQUERY",\r
+    "CQUERYM",\r
+    "CQUERYU",  /* experimental */\r
+    "NOTIFY",   /* experimental */\r
+    "UPDATE",\r
+    "6",\r
+    "7",\r
+    "8",\r
+    "9",\r
+    "10",\r
+    "11",\r
+    "12",\r
+    "13",\r
+    "ZONEINIT",\r
+    "ZONEREF",\r
+};\r
+\r
+const char *_res_resultcodes[] = {\r
+    "NOERROR",\r
+    "FORMERR",\r
+    "SERVFAIL",\r
+    "NXDOMAIN",\r
+    "NOTIMP",\r
+    "REFUSED",\r
+    "YXDOMAIN",\r
+    "YXRRSET",\r
+    "NXRRSET",\r
+    "NOTAUTH",\r
+    "ZONEERR",\r
+    "11",\r
+    "12",\r
+    "13",\r
+    "14",\r
+    "NOCHANGE",\r
+};\r
+\r
+#ifdef BIND_UPDATE\r
+const char *_res_sectioncodes[] = {\r
+    "ZONE",\r
+    "PREREQUISITES",\r
+    "UPDATE",\r
+    "ADDITIONAL",\r
+};\r
+#endif\r
diff --git a/StdLib/BsdSocketLib/res_debug.c b/StdLib/BsdSocketLib/res_debug.c
new file mode 100644 (file)
index 0000000..5cdc674
--- /dev/null
@@ -0,0 +1,988 @@
+/*\r
+ * Copyright (c) 1985\r
+ *    The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ *\r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.\r
+ *\r
+ * International Business Machines, Inc. (hereinafter called IBM) grants\r
+ * permission under its copyrights to use, copy, modify, and distribute this\r
+ * Software with or without fee, provided that the above copyright notice and\r
+ * all paragraphs of this notice appear in all copies, and that the name of IBM\r
+ * not be used in connection with the marketing of any product incorporating\r
+ * the Software or modifications thereof, without specific, written prior\r
+ * permission.\r
+ *\r
+ * To the extent it has a right to do so, IBM grants an immunity from suit\r
+ * under its patents, if any, for the use, sale or manufacture of products to\r
+ * the extent that such products are used for performing Domain Name System\r
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is\r
+ * granted for any product per se or for any other function of any product.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,\r
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,\r
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING\r
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN\r
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";\r
+static char rcsid[] = "$Id: res_debug.c,v 1.1.1.1 2003/11/19 01:51:36 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <math.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <time.h>\r
+\r
+#define SPRINTF(x) sprintf x\r
+\r
+extern const char *_res_opcodes[];\r
+extern const char *_res_resultcodes[];\r
+extern const char *_res_sectioncodes[];\r
+\r
+/*\r
+ * Print the current options.\r
+ */\r
+void\r
+fp_resstat(struct __res_state *statp, FILE *file) {\r
+    u_long mask;\r
+\r
+    fprintf(file, ";; res options:");\r
+    if (!statp)\r
+        statp = &_res;\r
+    for (mask = 1;  mask != 0;  mask <<= 1)\r
+        if (statp->options & mask)\r
+            fprintf(file, " %s", p_option(mask));\r
+    putc('\n', file);\r
+}\r
+\r
+static void\r
+do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file) {\r
+    int n, sflag, rrnum;\r
+    ns_opcode opcode;\r
+    ns_rr rr;\r
+\r
+    /*\r
+     * Print answer records.\r
+     */\r
+    sflag = (int)(_res.pfcode & pflag);\r
+    if (_res.pfcode && !sflag)\r
+        return;\r
+\r
+    opcode = ns_msg_getflag(*handle, ns_f_opcode);\r
+    rrnum = 0;\r
+    for (;;) {\r
+        if (ns_parserr(handle, section, rrnum, &rr)) {\r
+            if (errno != ENODEV)\r
+                fprintf(file, ";; ns_parserr: %s\n",\r
+                    strerror(errno));\r
+            else if (rrnum > 0 && sflag != 0 &&\r
+                 (_res.pfcode & RES_PRF_HEAD1))\r
+                putc('\n', file);\r
+            return;\r
+        }\r
+        if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1))\r
+            fprintf(file, ";; %s SECTION:\n",\r
+                p_section(section, opcode));\r
+        if (section == ns_s_qd)\r
+            fprintf(file, ";;\t%s, type = %s, class = %s\n",\r
+                ns_rr_name(rr),\r
+                p_type(ns_rr_type(rr)),\r
+                p_class(ns_rr_class(rr)));\r
+        else {\r
+            char *buf;\r
+            buf = (char*)malloc(2024);\r
+            if (buf) {\r
+                n = ns_sprintrr(handle, &rr, NULL, NULL,\r
+                        buf, sizeof buf);\r
+                if (n < 0) {\r
+                    fprintf(file, ";; ns_sprintrr: %s\n",\r
+                        strerror(errno));\r
+                    free(buf);\r
+                    return;\r
+                }\r
+                fputs(buf, file);\r
+                fputc('\n', file);\r
+                free(buf);\r
+            }\r
+        }\r
+        rrnum++;\r
+    }\r
+}\r
+\r
+void\r
+p_query(const u_char *msg) {\r
+    fp_query(msg, stdout);\r
+}\r
+\r
+void\r
+fp_query(const u_char *msg, FILE *file) {\r
+    fp_nquery(msg, PACKETSZ, file);\r
+}\r
+\r
+/*\r
+ * Print the contents of a query.\r
+ * This is intended to be primarily a debugging routine.\r
+ */\r
+void\r
+fp_nquery(const u_char *msg, int len, FILE *file) {\r
+    ns_msg handle;\r
+    int qdcount, ancount, nscount, arcount;\r
+    u_int opcode, rcode, id;\r
+\r
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1)\r
+        return;\r
+\r
+    if (ns_initparse(msg, len, &handle) < 0) {\r
+        fprintf(file, ";; ns_initparse: %s\n", strerror(errno));\r
+        return;\r
+    }\r
+    opcode = ns_msg_getflag(handle, ns_f_opcode);\r
+    rcode = ns_msg_getflag(handle, ns_f_rcode);\r
+    id = ns_msg_id(handle);\r
+    qdcount = ns_msg_count(handle, ns_s_qd);\r
+    ancount = ns_msg_count(handle, ns_s_an);\r
+    nscount = ns_msg_count(handle, ns_s_ns);\r
+    arcount = ns_msg_count(handle, ns_s_ar);\r
+\r
+    /*\r
+     * Print header fields.\r
+     */\r
+    if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || rcode)\r
+        fprintf(file,\r
+            ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",\r
+            _res_opcodes[opcode], _res_resultcodes[rcode], id);\r
+    if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))\r
+        putc(';', file);\r
+    if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {\r
+        fprintf(file, "; flags:");\r
+        if (ns_msg_getflag(handle, ns_f_qr))\r
+            fprintf(file, " qr");\r
+        if (ns_msg_getflag(handle, ns_f_aa))\r
+            fprintf(file, " aa");\r
+        if (ns_msg_getflag(handle, ns_f_tc))\r
+            fprintf(file, " tc");\r
+        if (ns_msg_getflag(handle, ns_f_rd))\r
+            fprintf(file, " rd");\r
+        if (ns_msg_getflag(handle, ns_f_ra))\r
+            fprintf(file, " ra");\r
+        if (ns_msg_getflag(handle, ns_f_z))\r
+            fprintf(file, " ??");\r
+        if (ns_msg_getflag(handle, ns_f_ad))\r
+            fprintf(file, " ad");\r
+        if (ns_msg_getflag(handle, ns_f_cd))\r
+            fprintf(file, " cd");\r
+    }\r
+    if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {\r
+        fprintf(file, "; %s: %d",\r
+            p_section(ns_s_qd, (int)opcode), qdcount);\r
+        fprintf(file, ", %s: %d",\r
+            p_section(ns_s_an, (int)opcode), ancount);\r
+        fprintf(file, ", %s: %d",\r
+            p_section(ns_s_ns, (int)opcode), nscount);\r
+        fprintf(file, ", %s: %d",\r
+            p_section(ns_s_ar, (int)opcode), arcount);\r
+    }\r
+    if ((!_res.pfcode) || (_res.pfcode &\r
+        (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {\r
+        putc('\n',file);\r
+    }\r
+    /*\r
+     * Print the various sections.\r
+     */\r
+    do_section(&handle, ns_s_qd, RES_PRF_QUES, file);\r
+    do_section(&handle, ns_s_an, RES_PRF_ANS, file);\r
+    do_section(&handle, ns_s_ns, RES_PRF_AUTH, file);\r
+    do_section(&handle, ns_s_ar, RES_PRF_ADD, file);\r
+    if (qdcount == 0 && ancount == 0 &&\r
+        nscount == 0 && arcount == 0)\r
+        putc('\n', file);\r
+}\r
+\r
+const u_char *\r
+p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {\r
+    char name[MAXDNAME];\r
+    int n;\r
+\r
+    if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)\r
+        return (NULL);\r
+    if (name[0] == '\0')\r
+        putc('.', file);\r
+    else\r
+        fputs(name, file);\r
+    return (cp + n);\r
+}\r
+\r
+const u_char *\r
+p_cdname(const u_char *cp, const u_char *msg, FILE *file) {\r
+    return (p_cdnname(cp, msg, PACKETSZ, file));\r
+}\r
+\r
+/* Return a fully-qualified domain name from a compressed name (with\r
+   length supplied).  */\r
+\r
+const u_char *\r
+p_fqnname(\r
+    const u_char *cp,\r
+    const u_char *msg,\r
+    int msglen,\r
+    char *name,\r
+    int namelen\r
+    )\r
+{\r
+    int n, newlen;\r
+\r
+    if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)\r
+        return (NULL);\r
+    newlen = (int)strlen(name);\r
+    if (newlen == 0 || name[newlen - 1] != '.') {\r
+        if (newlen + 1 >= namelen)  /* Lack space for final dot */\r
+            return (NULL);\r
+        else\r
+            strcpy(name + newlen, ".");\r
+    }\r
+    return (cp + n);\r
+}\r
+\r
+/* XXX: the rest of these functions need to become length-limited, too. */\r
+\r
+const u_char *\r
+p_fqname(const u_char *cp, const u_char *msg, FILE *file) {\r
+    char name[MAXDNAME];\r
+    const u_char *n;\r
+\r
+    n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);\r
+    if (n == NULL)\r
+        return (NULL);\r
+    fputs(name, file);\r
+    return (n);\r
+}\r
+\r
+/*\r
+ * Names of RR classes and qclasses.  Classes and qclasses are the same, except\r
+ * that C_ANY is a qclass but not a class.  (You can ask for records of class\r
+ * C_ANY, but you can't have any records of that class in the database.)\r
+ */\r
+const struct res_sym __p_class_syms[] = {\r
+    {C_IN,      "IN"},\r
+    {C_CHAOS,   "CHAOS"},\r
+    {C_HS,      "HS"},\r
+    {C_HS,      "HESIOD"},\r
+    {C_ANY,     "ANY"},\r
+    {C_NONE,    "NONE"},\r
+    {C_IN,      (char *)0}\r
+};\r
+\r
+/*\r
+ * Names of message sections.\r
+ */\r
+const struct res_sym __p_default_section_syms[] = {\r
+    {ns_s_qd,   "QUERY"},\r
+    {ns_s_an,   "ANSWER"},\r
+    {ns_s_ns,   "AUTHORITY"},\r
+    {ns_s_ar,   "ADDITIONAL"},\r
+    {0,             (char *)0}\r
+};\r
+\r
+const struct res_sym __p_update_section_syms[] = {\r
+    {S_ZONE,    "ZONE"},\r
+    {S_PREREQ,  "PREREQUISITE"},\r
+    {S_UPDATE,  "UPDATE"},\r
+    {S_ADDT,    "ADDITIONAL"},\r
+    {0,             (char *)0}\r
+};\r
+\r
+/*\r
+ * Names of RR types and qtypes.  Types and qtypes are the same, except\r
+ * that T_ANY is a qtype but not a type.  (You can ask for records of type\r
+ * T_ANY, but you can't have any records of that type in the database.)\r
+ */\r
+const struct res_sym __p_type_syms[] = {\r
+    {T_A,       "A",        "address"},\r
+    {T_NS,      "NS",       "name server"},\r
+    {T_MD,      "MD",       "mail destination (deprecated)"},\r
+    {T_MF,      "MF",       "mail forwarder (deprecated)"},\r
+    {T_CNAME,   "CNAME",    "canonical name"},\r
+    {T_SOA,     "SOA",      "start of authority"},\r
+    {T_MB,      "MB",       "mailbox"},\r
+    {T_MG,      "MG",       "mail group member"},\r
+    {T_MR,      "MR",       "mail rename"},\r
+    {T_NULL,    "NULL",     "null"},\r
+    {T_WKS,     "WKS",      "well-known service (deprecated)"},\r
+    {T_PTR,     "PTR",      "domain name pointer"},\r
+    {T_HINFO,   "HINFO",    "host information"},\r
+    {T_MINFO,   "MINFO",    "mailbox information"},\r
+    {T_MX,      "MX",       "mail exchanger"},\r
+    {T_TXT,     "TXT",      "text"},\r
+    {T_RP,      "RP",       "responsible person"},\r
+    {T_AFSDB,   "AFSDB",    "DCE or AFS server"},\r
+    {T_X25,     "X25",      "X25 address"},\r
+    {T_ISDN,    "ISDN",     "ISDN address"},\r
+    {T_RT,      "RT",       "router"},\r
+    {T_NSAP,    "NSAP",     "nsap address"},\r
+    {T_NSAP_PTR,    "NSAP_PTR", "domain name pointer"},\r
+    {T_SIG,     "SIG",      "signature"},\r
+    {T_KEY,     "KEY",      "key"},\r
+    {T_PX,      "PX",       "mapping information"},\r
+    {T_GPOS,    "GPOS",     "geographical position (withdrawn)"},\r
+    {T_AAAA,    "AAAA",     "IPv6 address"},\r
+    {T_LOC,     "LOC",      "location"},\r
+    {T_NXT,     "NXT",      "next valid name (unimplemented)"},\r
+    {T_EID,     "EID",      "endpoint identifier (unimplemented)"},\r
+    {T_NIMLOC,  "NIMLOC",   "NIMROD locator (unimplemented)"},\r
+    {T_SRV,     "SRV",      "server selection"},\r
+    {T_ATMA,    "ATMA",     "ATM address (unimplemented)"},\r
+    {T_IXFR,    "IXFR",     "incremental zone transfer"},\r
+    {T_AXFR,    "AXFR",     "zone transfer"},\r
+    {T_MAILB,   "MAILB",    "mailbox-related data (deprecated)"},\r
+    {T_MAILA,   "MAILA",    "mail agent (deprecated)"},\r
+    {T_NAPTR,   "NAPTR",    "URN Naming Authority"},\r
+    {T_ANY,     "ANY",      "\"any\""},\r
+    {0,         NULL,       NULL}\r
+};\r
+\r
+int\r
+sym_ston(const struct res_sym *syms, const char *name, int *success) {\r
+    for ((void)NULL; syms->name != 0; syms++) {\r
+        if (strcasecmp (name, syms->name) == 0) {\r
+            if (success)\r
+                *success = 1;\r
+            return (syms->number);\r
+        }\r
+    }\r
+    if (success)\r
+        *success = 0;\r
+    return (syms->number);      /* The default value. */\r
+}\r
+\r
+const char *\r
+sym_ntos(const struct res_sym *syms, int number, int *success) {\r
+    static char unname[20];\r
+\r
+    for ((void)NULL; syms->name != 0; syms++) {\r
+        if (number == syms->number) {\r
+            if (success)\r
+                *success = 1;\r
+            return (syms->name);\r
+        }\r
+    }\r
+\r
+    sprintf(unname, "%d", number);\r
+    if (success)\r
+        *success = 0;\r
+    return (unname);\r
+}\r
+\r
+const char *\r
+sym_ntop(const struct res_sym *syms, int number, int *success) {\r
+    static char unname[20];\r
+\r
+    for ((void)NULL; syms->name != 0; syms++) {\r
+        if (number == syms->number) {\r
+            if (success)\r
+                *success = 1;\r
+            return (syms->humanname);\r
+        }\r
+    }\r
+    sprintf(unname, "%d", number);\r
+    if (success)\r
+        *success = 0;\r
+    return (unname);\r
+}\r
+\r
+/*\r
+ * Return a string for the type.\r
+ */\r
+const char *\r
+p_type(int type) {\r
+    return (sym_ntos(__p_type_syms, type, (int *)0));\r
+}\r
+\r
+/*\r
+ * Return a string for the type.\r
+ */\r
+const char *\r
+p_section(int section, int opcode) {\r
+    const struct res_sym *symbols;\r
+\r
+    switch (opcode) {\r
+    case ns_o_update:\r
+        symbols = __p_update_section_syms;\r
+        break;\r
+    default:\r
+        symbols = __p_default_section_syms;\r
+        break;\r
+    }\r
+    return (sym_ntos(symbols, section, (int *)0));\r
+}\r
+\r
+/*\r
+ * Return a mnemonic for class.\r
+ */\r
+const char *\r
+p_class(int class) {\r
+    return (sym_ntos(__p_class_syms, class, (int *)0));\r
+}\r
+\r
+/*\r
+ * Return a mnemonic for an option\r
+ */\r
+const char *\r
+p_option(u_long option) {\r
+    static char nbuf[40];\r
+\r
+    switch (option) {\r
+    case RES_INIT:      return "init";\r
+    case RES_DEBUG:     return "debug";\r
+    case RES_AAONLY:    return "aaonly(unimpl)";\r
+    case RES_USEVC:     return "usevc";\r
+    case RES_PRIMARY:   return "primry(unimpl)";\r
+    case RES_IGNTC:     return "igntc";\r
+    case RES_RECURSE:   return "recurs";\r
+    case RES_DEFNAMES:  return "defnam";\r
+    case RES_STAYOPEN:  return "styopn";\r
+    case RES_DNSRCH:    return "dnsrch";\r
+    case RES_INSECURE1: return "insecure1";\r
+    case RES_INSECURE2: return "insecure2";\r
+    default:        sprintf(nbuf, "?0x%lx?", (u_long)option);\r
+                return (nbuf);\r
+    }\r
+}\r
+\r
+/*\r
+ * Return a mnemonic for a time to live.\r
+ */\r
+const char *\r
+p_time(u_int32_t value) {\r
+    static char nbuf[40];\r
+\r
+    if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)\r
+        sprintf(nbuf, "%u", value);\r
+    return (nbuf);\r
+}\r
+\r
+\r
+/*\r
+ * routines to convert between on-the-wire RR format and zone file format.\r
+ * Does not contain conversion to/from decimal degrees; divide or multiply\r
+ * by 60*60*1000 for that.\r
+ */\r
+\r
+static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,\r
+                      1000000,10000000,100000000,1000000000};\r
+\r
+/* takes an XeY precision/size value, returns a string representation. */\r
+static const char *\r
+precsize_ntoa(\r
+    u_int8_t prec\r
+    )\r
+{\r
+    static char retbuf[sizeof "90000000.00"];\r
+    unsigned long val;\r
+    int mantissa, exponent;\r
+\r
+    mantissa = (int)((prec >> 4) & 0x0f) % 10;\r
+    exponent = (int)((prec >> 0) & 0x0f) % 10;\r
+\r
+    val = mantissa * poweroften[exponent];\r
+\r
+    (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);\r
+    return (retbuf);\r
+}\r
+\r
+/* converts ascii size/precision X * 10**Y(cm) to 0xXY.  moves pointer. */\r
+static u_int8_t\r
+precsize_aton(\r
+    char **strptr\r
+    )\r
+{\r
+    unsigned int mval = 0, cmval = 0;\r
+    u_int8_t retval = 0;\r
+    char *cp;\r
+    int exponent;\r
+    int mantissa;\r
+\r
+    cp = *strptr;\r
+\r
+    while (isdigit(*cp))\r
+        mval = mval * 10 + (*cp++ - '0');\r
+\r
+    if (*cp == '.') {       /* centimeters */\r
+        cp++;\r
+        if (isdigit(*cp)) {\r
+            cmval = (*cp++ - '0') * 10;\r
+            if (isdigit(*cp)) {\r
+                cmval += (*cp++ - '0');\r
+            }\r
+        }\r
+    }\r
+    cmval = (mval * 100) + cmval;\r
+\r
+    for (exponent = 0; exponent < 9; exponent++)\r
+        if (cmval < poweroften[exponent+1])\r
+            break;\r
+\r
+    mantissa = cmval / poweroften[exponent];\r
+    if (mantissa > 9)\r
+        mantissa = 9;\r
+\r
+    retval = (u_int8_t)((mantissa << 4) | exponent);\r
+\r
+    *strptr = cp;\r
+\r
+    return (retval);\r
+}\r
+\r
+/* converts ascii lat/lon to unsigned encoded 32-bit number.  moves pointer. */\r
+static u_int32_t\r
+latlon2ul(\r
+    char **latlonstrptr,\r
+    int *which\r
+    )\r
+{\r
+    char *cp;\r
+    u_int32_t retval;\r
+    int deg = 0, min = 0, secs = 0, secsfrac = 0;\r
+\r
+    cp = *latlonstrptr;\r
+\r
+    while (isdigit(*cp))\r
+        deg = deg * 10 + (*cp++ - '0');\r
+\r
+    while (isspace(*cp))\r
+        cp++;\r
+\r
+    if (!(isdigit(*cp)))\r
+        goto fndhemi;\r
+\r
+    while (isdigit(*cp))\r
+        min = min * 10 + (*cp++ - '0');\r
+\r
+    while (isspace(*cp))\r
+        cp++;\r
+\r
+    if (!(isdigit(*cp)))\r
+        goto fndhemi;\r
+\r
+    while (isdigit(*cp))\r
+        secs = secs * 10 + (*cp++ - '0');\r
+\r
+    if (*cp == '.') {       /* decimal seconds */\r
+        cp++;\r
+        if (isdigit(*cp)) {\r
+            secsfrac = (*cp++ - '0') * 100;\r
+            if (isdigit(*cp)) {\r
+                secsfrac += (*cp++ - '0') * 10;\r
+                if (isdigit(*cp)) {\r
+                    secsfrac += (*cp++ - '0');\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    while (!isspace(*cp))   /* if any trailing garbage */\r
+        cp++;\r
+\r
+    while (isspace(*cp))\r
+        cp++;\r
+\r
+ fndhemi:\r
+    switch (*cp) {\r
+    case 'N': case 'n':\r
+    case 'E': case 'e':\r
+        retval = ((unsigned)1<<31)\r
+            + (((((deg * 60) + min) * 60) + secs) * 1000)\r
+            + secsfrac;\r
+        break;\r
+    case 'S': case 's':\r
+    case 'W': case 'w':\r
+        retval = ((unsigned)1<<31)\r
+            - (((((deg * 60) + min) * 60) + secs) * 1000)\r
+            - secsfrac;\r
+        break;\r
+    default:\r
+        retval = 0; /* invalid value -- indicates error */\r
+        break;\r
+    }\r
+\r
+    switch (*cp) {\r
+    case 'N': case 'n':\r
+    case 'S': case 's':\r
+        *which = 1; /* latitude */\r
+        break;\r
+    case 'E': case 'e':\r
+    case 'W': case 'w':\r
+        *which = 2; /* longitude */\r
+        break;\r
+    default:\r
+        *which = 0; /* error */\r
+        break;\r
+    }\r
+\r
+    cp++;           /* skip the hemisphere */\r
+\r
+    while (!isspace(*cp))   /* if any trailing garbage */\r
+        cp++;\r
+\r
+    while (isspace(*cp))    /* move to next field */\r
+        cp++;\r
+\r
+    *latlonstrptr = cp;\r
+\r
+    return (retval);\r
+}\r
+\r
+/* converts a zone file representation in a string to an RDATA on-the-wire\r
+ * representation. */\r
+int\r
+loc_aton(\r
+    const char *ascii,\r
+    u_char *binary\r
+    )\r
+{\r
+    const char *cp, *maxcp;\r
+    u_char *bcp;\r
+\r
+    u_int32_t latit = 0, longit = 0, alt = 0;\r
+    u_int32_t lltemp1 = 0, lltemp2 = 0;\r
+    int altmeters = 0, altfrac = 0, altsign = 1;\r
+    u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */\r
+    u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */\r
+    u_int8_t siz = 0x12;    /* default = 1e2 cm = 1.00m */\r
+    int which1 = 0, which2 = 0;\r
+\r
+    cp = ascii;\r
+    maxcp = cp + strlen(ascii);\r
+\r
+    lltemp1 = latlon2ul((char **)&cp, &which1);\r
+\r
+    lltemp2 = latlon2ul((char **)&cp, &which2);\r
+\r
+    switch (which1 + which2) {\r
+    case 3:         /* 1 + 2, the only valid combination */\r
+        if ((which1 == 1) && (which2 == 2)) { /* normal case */\r
+            latit = lltemp1;\r
+            longit = lltemp2;\r
+        } else if ((which1 == 2) && (which2 == 1)) { /* reversed */\r
+            longit = lltemp1;\r
+            latit = lltemp2;\r
+        } else {    /* some kind of brokenness */\r
+            return (0);\r
+        }\r
+        break;\r
+    default:        /* we didn't get one of each */\r
+        return (0);\r
+    }\r
+\r
+    /* altitude */\r
+    if (*cp == '-') {\r
+        altsign = -1;\r
+        cp++;\r
+    }\r
+\r
+    if (*cp == '+')\r
+        cp++;\r
+\r
+    while (isdigit(*cp))\r
+        altmeters = altmeters * 10 + (*cp++ - '0');\r
+\r
+    if (*cp == '.') {       /* decimal meters */\r
+        cp++;\r
+        if (isdigit(*cp)) {\r
+            altfrac = (*cp++ - '0') * 10;\r
+            if (isdigit(*cp)) {\r
+                altfrac += (*cp++ - '0');\r
+            }\r
+        }\r
+    }\r
+\r
+    alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));\r
+\r
+    while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */\r
+        cp++;\r
+\r
+    while (isspace(*cp) && (cp < maxcp))\r
+        cp++;\r
+\r
+    if (cp >= maxcp)\r
+        goto defaults;\r
+\r
+    siz = precsize_aton((char **)&cp);\r
+\r
+    while (!isspace(*cp) && (cp < maxcp))   /* if trailing garbage or m */\r
+        cp++;\r
+\r
+    while (isspace(*cp) && (cp < maxcp))\r
+        cp++;\r
+\r
+    if (cp >= maxcp)\r
+        goto defaults;\r
+\r
+    hp = precsize_aton((char **)&cp);\r
+\r
+    while (!isspace(*cp) && (cp < maxcp))   /* if trailing garbage or m */\r
+        cp++;\r
+\r
+    while (isspace(*cp) && (cp < maxcp))\r
+        cp++;\r
+\r
+    if (cp >= maxcp)\r
+        goto defaults;\r
+\r
+    vp = precsize_aton((char **)&cp);\r
+\r
+ defaults:\r
+\r
+    bcp = binary;\r
+    *bcp++ = (u_int8_t) 0;  /* version byte */\r
+    *bcp++ = siz;\r
+    *bcp++ = hp;\r
+    *bcp++ = vp;\r
+    PUTLONG(latit,bcp);\r
+    PUTLONG(longit,bcp);\r
+    PUTLONG(alt,bcp);\r
+\r
+    return (16);        /* size of RR in octets */\r
+}\r
+\r
+/* takes an on-the-wire LOC RR and formats it in a human readable format. */\r
+const char *\r
+loc_ntoa(\r
+    const u_char *binary,\r
+    char *ascii\r
+    )\r
+{\r
+    static char *error = "?";\r
+    const u_char *cp = binary;\r
+\r
+    int latdeg, latmin, latsec, latsecfrac;\r
+    int longdeg, longmin, longsec, longsecfrac;\r
+    char northsouth, eastwest;\r
+    int altmeters, altfrac, altsign;\r
+\r
+    const u_int32_t referencealt = 100000 * 100;\r
+\r
+    int32_t latval, longval, altval;\r
+    u_int32_t templ;\r
+    u_int8_t sizeval, hpval, vpval, versionval;\r
+\r
+    char *sizestr, *hpstr, *vpstr;\r
+\r
+    versionval = *cp++;\r
+\r
+    if (versionval) {\r
+        (void) sprintf(ascii, "; error: unknown LOC RR version");\r
+        return (ascii);\r
+    }\r
+\r
+    sizeval = *cp++;\r
+\r
+    hpval = *cp++;\r
+    vpval = *cp++;\r
+\r
+    GETLONG(templ, cp);\r
+    latval = (templ - ((unsigned)1<<31));\r
+\r
+    GETLONG(templ, cp);\r
+    longval = (templ - ((unsigned)1<<31));\r
+\r
+    GETLONG(templ, cp);\r
+    if (templ < referencealt) { /* below WGS 84 spheroid */\r
+        altval = referencealt - templ;\r
+        altsign = -1;\r
+    } else {\r
+        altval = templ - referencealt;\r
+        altsign = 1;\r
+    }\r
+\r
+    if (latval < 0) {\r
+        northsouth = 'S';\r
+        latval = -latval;\r
+    } else\r
+        northsouth = 'N';\r
+\r
+    latsecfrac = latval % 1000;\r
+    latval = latval / 1000;\r
+    latsec = latval % 60;\r
+    latval = latval / 60;\r
+    latmin = latval % 60;\r
+    latval = latval / 60;\r
+    latdeg = latval;\r
+\r
+    if (longval < 0) {\r
+        eastwest = 'W';\r
+        longval = -longval;\r
+    } else\r
+        eastwest = 'E';\r
+\r
+    longsecfrac = longval % 1000;\r
+    longval = longval / 1000;\r
+    longsec = longval % 60;\r
+    longval = longval / 60;\r
+    longmin = longval % 60;\r
+    longval = longval / 60;\r
+    longdeg = longval;\r
+\r
+    altfrac = altval % 100;\r
+    altmeters = (altval / 100) * altsign;\r
+\r
+    if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)\r
+        sizestr = error;\r
+    if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)\r
+        hpstr = error;\r
+    if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)\r
+        vpstr = error;\r
+\r
+    sprintf(ascii,\r
+          "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",\r
+        latdeg, latmin, latsec, latsecfrac, northsouth,\r
+        longdeg, longmin, longsec, longsecfrac, eastwest,\r
+        altmeters, altfrac, sizestr, hpstr, vpstr);\r
+\r
+    if (sizestr != error)\r
+        free(sizestr);\r
+    if (hpstr != error)\r
+        free(hpstr);\r
+    if (vpstr != error)\r
+        free(vpstr);\r
+\r
+    return (ascii);\r
+}\r
+\r
+\r
+/* Return the number of DNS hierarchy levels in the name. */\r
+int\r
+dn_count_labels(const char *name) {\r
+    int i, len, count;\r
+\r
+    len = (int)strlen(name);\r
+    for (i = 0, count = 0; i < len; i++) {\r
+        /* XXX need to check for \. or use named's nlabels(). */\r
+        if (name[i] == '.')\r
+            count++;\r
+    }\r
+\r
+    /* don't count initial wildcard */\r
+    if (name[0] == '*')\r
+        if (count)\r
+            count--;\r
+\r
+    /* don't count the null label for root. */\r
+    /* if terminating '.' not found, must adjust */\r
+    /* count to include last label */\r
+    if (len > 0 && name[len-1] != '.')\r
+        count++;\r
+    return (count);\r
+}\r
+\r
+\r
+/*\r
+ * Make dates expressed in seconds-since-Jan-1-1970 easy to read.\r
+ * SIG records are required to be printed like this, by the Secure DNS RFC.\r
+ */\r
+char *\r
+p_secstodate (u_long secs) {\r
+    static char output[15];     /* YYYYMMDDHHMMSS and null */\r
+    time_t clock = (time_t)secs;\r
+    struct tm *time;\r
+\r
+    time = gmtime(&clock);\r
+    time->tm_year += 1900;\r
+    time->tm_mon += 1;\r
+    sprintf(output, "%04d%02d%02d%02d%02d%02d",\r
+        time->tm_year, time->tm_mon, time->tm_mday,\r
+        time->tm_hour, time->tm_min, time->tm_sec);\r
+    return (output);\r
+}\r
diff --git a/StdLib/BsdSocketLib/res_init.c b/StdLib/BsdSocketLib/res_init.c
new file mode 100644 (file)
index 0000000..613a76a
--- /dev/null
@@ -0,0 +1,514 @@
+/*\r
+ * Copyright (c) 1985, 1989, 1993\r
+ *    The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ *\r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)res_init.c  8.1 (Berkeley) 6/7/93";\r
+static char orig_rcsid[] = "From: Id: res_init.c,v 8.7 1996/11/18 09:10:04 vixie Exp $";\r
+static char rcsid[] = "$Id: res_init.c,v 1.1.1.1 2003/11/19 01:51:37 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <sys/time.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+#include <ctype.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+\r
+#include "res_config.h"\r
+\r
+static void res_setoptions __P((char *, char *));\r
+\r
+#ifdef RESOLVSORT\r
+static const char sort_mask[] = "/&";\r
+#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)\r
+static u_int32_t net_mask __P((struct in_addr));\r
+#endif\r
+\r
+#if !defined(isascii) /* XXX - could be a function */\r
+# define isascii(c) (!(c & 0200))\r
+#endif\r
+\r
+/*\r
+ * Resolver state default settings.\r
+ */\r
+\r
+struct __res_state _res\r
+# if defined(__BIND_RES_TEXT)\r
+    = { RES_TIMEOUT, }  /* Motorola, et al. */\r
+# endif\r
+    ;\r
+\r
+\r
+/*\r
+ * Set up default settings.  If the configuration file exist, the values\r
+ * there will have precedence.  Otherwise, the server address is set to\r
+ * INADDR_ANY and the default domain name comes from the gethostname().\r
+ *\r
+ * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1\r
+ * rather than INADDR_ANY ("0.0.0.0") as the default name server address\r
+ * since it was noted that INADDR_ANY actually meant ``the first interface\r
+ * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,\r
+ * it had to be "up" in order for you to reach your own name server.  It\r
+ * was later decided that since the recommended practice is to always\r
+ * install local static routes through 127.0.0.1 for all your network\r
+ * interfaces, that we could solve this problem without a code change.\r
+ *\r
+ * The configuration file should always be used, since it is the only way\r
+ * to specify a default domain.  If you are running a server on your local\r
+ * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"\r
+ * in the configuration file.\r
+ *\r
+ * Return 0 if completes successfully, -1 on error\r
+ */\r
+int\r
+res_init()\r
+{\r
+    register FILE *fp;\r
+    register char *cp, **pp;\r
+    register int n;\r
+    char buf[MAXDNAME];\r
+    int nserv = 0;    /* number of nameserver records read from file */\r
+    int haveenv = 0;\r
+    int havesearch = 0;\r
+#ifdef RESOLVSORT\r
+    int nsort = 0;\r
+    char *net;\r
+#endif\r
+#ifndef RFC1535\r
+    int dots;\r
+#endif\r
+\r
+    /*\r
+     * These three fields used to be statically initialized.  This made\r
+     * it hard to use this code in a shared library.  It is necessary,\r
+     * now that we're doing dynamic initialization here, that we preserve\r
+     * the old semantics: if an application modifies one of these three\r
+     * fields of _res before res_init() is called, res_init() will not\r
+     * alter them.  Of course, if an application is setting them to\r
+     * _zero_ before calling res_init(), hoping to override what used\r
+     * to be the static default, we can't detect it and unexpected results\r
+     * will follow.  Zero for any of these fields would make no sense,\r
+     * so one can safely assume that the applications were already getting\r
+     * unexpected results.\r
+     *\r
+     * _res.options is tricky since some apps were known to diddle the bits\r
+     * before res_init() was first called. We can't replicate that semantic\r
+     * with dynamic initialization (they may have turned bits off that are\r
+     * set in RES_DEFAULT).  Our solution is to declare such applications\r
+     * "broken".  They could fool us by setting RES_INIT but none do (yet).\r
+     */\r
+    if (!_res.retrans)\r
+        _res.retrans = RES_TIMEOUT;\r
+    if (!_res.retry)\r
+        _res.retry = 4;\r
+    if (!(_res.options & RES_INIT))\r
+        _res.options = RES_DEFAULT;\r
+\r
+    /*\r
+     * This one used to initialize implicitly to zero, so unless the app\r
+     * has set it to something in particular, we can randomize it now.\r
+     */\r
+    if (!_res.id)\r
+        _res.id = (u_short)res_randomid();\r
+\r
+#ifdef USELOOPBACK\r
+    _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);\r
+#else\r
+    _res.nsaddr.sin_addr.s_addr = INADDR_ANY;\r
+#endif\r
+    _res.nsaddr.sin_family = AF_INET;\r
+    _res.nsaddr.sin_port = htons(NAMESERVER_PORT);\r
+    _res.nscount = 1;\r
+    _res.ndots = 1;\r
+    _res.pfcode = 0;\r
+\r
+    /* Allow user to override the local domain definition */\r
+#ifdef _ORG_FREEBSD_\r
+    if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL)\r
+#else\r
+    if ((cp = getenv("LOCALDOMAIN")) != NULL)\r
+#endif\r
+    {\r
+        (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);\r
+        _res.defdname[sizeof(_res.defdname) - 1] = '\0';\r
+        haveenv++;\r
+\r
+        /*\r
+         * Set search list to be blank-separated strings\r
+         * from rest of env value.  Permits users of LOCALDOMAIN\r
+         * to still have a search list, and anyone to set the\r
+         * one that they want to use as an individual (even more\r
+         * important now that the rfc1535 stuff restricts searches)\r
+         */\r
+        cp = _res.defdname;\r
+        pp = _res.dnsrch;\r
+        *pp++ = cp;\r
+        for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {\r
+            if (*cp == '\n')    /* silly backwards compat */\r
+                break;\r
+            else if (*cp == ' ' || *cp == '\t') {\r
+                *cp = 0;\r
+                n = 1;\r
+            } else if (n) {\r
+                *pp++ = cp;\r
+                n = 0;\r
+                havesearch = 1;\r
+            }\r
+        }\r
+        /* null terminate last domain if there are excess */\r
+        while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')\r
+            cp++;\r
+        *cp = '\0';\r
+        *pp++ = 0;\r
+    }\r
+\r
+#define MATCH(line, name) \\r
+    (!strncmp(line, name, sizeof(name) - 1) && \\r
+    (line[sizeof(name) - 1] == ' ' || \\r
+     line[sizeof(name) - 1] == '\t'))\r
+\r
+    if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {\r
+        /* read the config file */\r
+        while (fgets(buf, sizeof(buf), fp) != NULL) {\r
+        /* skip comments */\r
+        if (*buf == ';' || *buf == '#')\r
+            continue;\r
+        /* read default domain name */\r
+        if (MATCH(buf, "domain")) {\r
+            if (haveenv)    /* skip if have from environ */\r
+                continue;\r
+            cp = buf + sizeof("domain") - 1;\r
+            while (*cp == ' ' || *cp == '\t')\r
+                cp++;\r
+            if ((*cp == '\0') || (*cp == '\n'))\r
+                continue;\r
+            strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);\r
+            _res.defdname[sizeof(_res.defdname) - 1] = '\0';\r
+            if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)\r
+                *cp = '\0';\r
+            havesearch = 0;\r
+            continue;\r
+        }\r
+        /* set search list */\r
+        if (MATCH(buf, "search")) {\r
+            if (haveenv)    /* skip if have from environ */\r
+                continue;\r
+            cp = buf + sizeof("search") - 1;\r
+            while (*cp == ' ' || *cp == '\t')\r
+                cp++;\r
+            if ((*cp == '\0') || (*cp == '\n'))\r
+                continue;\r
+            strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);\r
+            _res.defdname[sizeof(_res.defdname) - 1] = '\0';\r
+            if ((cp = strchr(_res.defdname, '\n')) != NULL)\r
+                *cp = '\0';\r
+            /*\r
+             * Set search list to be blank-separated strings\r
+             * on rest of line.\r
+             */\r
+            cp = _res.defdname;\r
+            pp = _res.dnsrch;\r
+            *pp++ = cp;\r
+            for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {\r
+                if (*cp == ' ' || *cp == '\t') {\r
+                    *cp = 0;\r
+                    n = 1;\r
+                } else if (n) {\r
+                    *pp++ = cp;\r
+                    n = 0;\r
+                }\r
+            }\r
+            /* null terminate last domain if there are excess */\r
+            while (*cp != '\0' && *cp != ' ' && *cp != '\t')\r
+                cp++;\r
+            *cp = '\0';\r
+            *pp++ = 0;\r
+            havesearch = 1;\r
+            continue;\r
+        }\r
+        /* read nameservers to query */\r
+        if (MATCH(buf, "nameserver") && nserv < MAXNS) {\r
+            struct in_addr a;\r
+\r
+            cp = buf + sizeof("nameserver") - 1;\r
+            while (*cp == ' ' || *cp == '\t')\r
+            cp++;\r
+            if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {\r
+            _res.nsaddr_list[nserv].sin_addr = a;\r
+            _res.nsaddr_list[nserv].sin_family = AF_INET;\r
+            _res.nsaddr_list[nserv].sin_port =\r
+                htons(NAMESERVER_PORT);\r
+            nserv++;\r
+            }\r
+            continue;\r
+        }\r
+#ifdef RESOLVSORT\r
+        if (MATCH(buf, "sortlist")) {\r
+            struct in_addr a;\r
+\r
+            cp = buf + sizeof("sortlist") - 1;\r
+            while (nsort < MAXRESOLVSORT) {\r
+            while (*cp == ' ' || *cp == '\t')\r
+                cp++;\r
+            if (*cp == '\0' || *cp == '\n' || *cp == ';')\r
+                break;\r
+            net = cp;\r
+            while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&\r
+                   isascii(*cp) && !isspace(*cp))\r
+                cp++;\r
+            n = *cp;\r
+            *cp = 0;\r
+            if (inet_aton(net, &a)) {\r
+                _res.sort_list[nsort].addr = a;\r
+                if (ISSORTMASK(n)) {\r
+                *cp++ = (char)n;\r
+                net = cp;\r
+                while (*cp && *cp != ';' &&\r
+                    isascii(*cp) && !isspace(*cp))\r
+                    cp++;\r
+                n = *cp;\r
+                *cp = 0;\r
+                if (inet_aton(net, &a)) {\r
+                    _res.sort_list[nsort].mask = a.s_addr;\r
+                } else {\r
+                    _res.sort_list[nsort].mask =\r
+                    net_mask(_res.sort_list[nsort].addr);\r
+                }\r
+                } else {\r
+                _res.sort_list[nsort].mask =\r
+                    net_mask(_res.sort_list[nsort].addr);\r
+                }\r
+                nsort++;\r
+            }\r
+            *cp = (char)n;\r
+            }\r
+            continue;\r
+        }\r
+#endif\r
+        if (MATCH(buf, "options")) {\r
+            res_setoptions(buf + sizeof("options") - 1, "conf");\r
+            continue;\r
+        }\r
+        }\r
+        if (nserv > 1)\r
+        _res.nscount = nserv;\r
+#ifdef RESOLVSORT\r
+        _res.nsort = nsort;\r
+#endif\r
+        (void) fclose(fp);\r
+    }\r
+    if (_res.defdname[0] == 0 &&\r
+        gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&\r
+        (cp = strchr(buf, '.')) != NULL)\r
+        strcpy(_res.defdname, cp + 1);\r
+\r
+    /* find components of local domain that might be searched */\r
+    if (havesearch == 0) {\r
+        pp = _res.dnsrch;\r
+        *pp++ = _res.defdname;\r
+        *pp = NULL;\r
+\r
+#ifndef RFC1535\r
+        dots = 0;\r
+        for (cp = _res.defdname; *cp; cp++)\r
+            dots += (*cp == '.');\r
+\r
+        cp = _res.defdname;\r
+        while (pp < _res.dnsrch + MAXDFLSRCH) {\r
+            if (dots < LOCALDOMAINPARTS)\r
+                break;\r
+            cp = strchr(cp, '.') + 1;    /* we know there is one */\r
+            *pp++ = cp;\r
+            dots--;\r
+        }\r
+        *pp = NULL;\r
+#ifdef DEBUG\r
+        if (_res.options & RES_DEBUG) {\r
+            printf(";; res_init()... default dnsrch list:\n");\r
+            for (pp = _res.dnsrch; *pp; pp++)\r
+                printf(";;\t%s\n", *pp);\r
+            printf(";;\t..END..\n");\r
+        }\r
+#endif\r
+#endif /* !RFC1535 */\r
+    }\r
+\r
+#ifdef _ORG_FREEBSD_\r
+    if (issetugid())\r
+#else\r
+    if (1)\r
+#endif\r
+        _res.options |= RES_NOALIASES;\r
+    else if ((cp = getenv("RES_OPTIONS")) != NULL)\r
+        res_setoptions(cp, "env");\r
+    _res.options |= RES_INIT;\r
+    if ( 0 == nserv ) {\r
+      return -1;\r
+    }\r
+    return (0);\r
+}\r
+\r
+static void\r
+res_setoptions(\r
+    char *options,\r
+    char *source\r
+    )\r
+{\r
+    char *cp = options;\r
+    int i;\r
+\r
+#ifdef DEBUG\r
+    if (_res.options & RES_DEBUG)\r
+        printf(";; res_setoptions(\"%s\", \"%s\")...\n",\r
+               options, source);\r
+#endif\r
+    while (*cp) {\r
+        /* skip leading and inner runs of spaces */\r
+        while (*cp == ' ' || *cp == '\t')\r
+            cp++;\r
+        /* search for and process individual options */\r
+        if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {\r
+            i = atoi(cp + sizeof("ndots:") - 1);\r
+            if (i <= RES_MAXNDOTS)\r
+                _res.ndots = i;\r
+            else\r
+                _res.ndots = RES_MAXNDOTS;\r
+#ifdef DEBUG\r
+            if (_res.options & RES_DEBUG)\r
+                printf(";;\tndots=%d\n", _res.ndots);\r
+#endif\r
+        } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {\r
+#ifdef DEBUG\r
+            if (!(_res.options & RES_DEBUG)) {\r
+                printf(";; res_setoptions(\"%s\", \"%s\")..\n",\r
+                       options, source);\r
+                _res.options |= RES_DEBUG;\r
+            }\r
+            printf(";;\tdebug\n");\r
+#endif\r
+        } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {\r
+            _res.options |= RES_USE_INET6;\r
+        } else if (!strncmp(cp, "no_tld_query", sizeof("no_tld_query") - 1)) {\r
+            _res.options |= RES_NOTLDQUERY;\r
+        } else {\r
+            /* XXX - print a warning here? */\r
+        }\r
+        /* skip to next run of spaces */\r
+        while (*cp && *cp != ' ' && *cp != '\t')\r
+            cp++;\r
+    }\r
+}\r
+\r
+#ifdef RESOLVSORT\r
+/* XXX - should really support CIDR which means explicit masks always. */\r
+static u_int32_t\r
+net_mask(\r
+    struct in_addr in\r
+    )\r
+{\r
+    register u_int32_t i = ntohl(in.s_addr);\r
+\r
+    if (IN_CLASSA(i))\r
+        return (htonl(IN_CLASSA_NET));\r
+    else if (IN_CLASSB(i))\r
+        return (htonl(IN_CLASSB_NET));\r
+    return (htonl(IN_CLASSC_NET));\r
+}\r
+#endif\r
+\r
+u_int\r
+res_randomid()\r
+{\r
+    struct timeval now;\r
+\r
+    gettimeofday(&now, NULL);\r
+    return (0xffff & (now.tv_sec ^ now.tv_usec /* ^ getpid() */));\r
+}\r
diff --git a/StdLib/BsdSocketLib/res_mkquery.c b/StdLib/BsdSocketLib/res_mkquery.c
new file mode 100644 (file)
index 0000000..2559f22
--- /dev/null
@@ -0,0 +1,211 @@
+/*\r
+ * Copyright (c) 1985, 1993\r
+ *    The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ *\r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)res_mkquery.c   8.1 (Berkeley) 6/4/93";\r
+static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.9 1997/04/24 22:22:36 vixie Exp $";\r
+static char rcsid[] = "$Id: res_mkquery.c,v 1.1.1.1 2003/11/19 01:51:37 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <netinet/in.h>\r
+#include <arpa/nameser.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "res_config.h"\r
+\r
+/*\r
+ * Form all types of queries.\r
+ * Returns the size of the result or -1.\r
+ */\r
+int\r
+res_mkquery(\r
+    int op,         /* opcode of query */\r
+    const char *dname,  /* domain name */\r
+    int class,          /* class of query */\r
+    int type,           /* type of query */\r
+    const u_char *data, /* resource record data */\r
+    int datalen,        /* length of data */\r
+    const u_char *newrr_in, /* new rr for modify or append */\r
+    u_char *buf,        /* buffer to put query */\r
+    int buflen     /* size of buffer */\r
+    )\r
+{\r
+    register HEADER *hp;\r
+    register u_char *cp;\r
+    register int n;\r
+    u_char *dnptrs[20], **dpp, **lastdnptr;\r
+\r
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+        h_errno = NETDB_INTERNAL;\r
+        return (-1);\r
+    }\r
+#ifdef DEBUG\r
+    if (_res.options & RES_DEBUG)\r
+        printf(";; res_mkquery(%d, %s, %d, %d)\n",\r
+               op, dname, class, type);\r
+#endif\r
+    /*\r
+     * Initialize header fields.\r
+     */\r
+    if ((buf == NULL) || (buflen < HFIXEDSZ))\r
+        return (-1);\r
+    memset(buf, 0, HFIXEDSZ);\r
+    hp = (HEADER *) buf;\r
+    hp->id = htons(++_res.id);\r
+    hp->opcode = op;\r
+    hp->rd = (_res.options & RES_RECURSE) != 0;\r
+    hp->rcode = NOERROR;\r
+    cp = buf + HFIXEDSZ;\r
+    buflen -= HFIXEDSZ;\r
+    dpp = dnptrs;\r
+    *dpp++ = buf;\r
+    *dpp++ = NULL;\r
+    lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];\r
+    /*\r
+     * perform opcode specific processing\r
+     */\r
+    switch (op) {\r
+    case QUERY: /*FALLTHROUGH*/\r
+    case NS_NOTIFY_OP:\r
+        if ((buflen -= QFIXEDSZ) < 0)\r
+            return (-1);\r
+        if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)\r
+            return (-1);\r
+        cp += n;\r
+        buflen -= n;\r
+        __putshort((u_int16_t)type, cp);\r
+        cp += INT16SZ;\r
+        __putshort((u_int16_t)class, cp);\r
+        cp += INT16SZ;\r
+        hp->qdcount = htons(1);\r
+        if (op == QUERY || data == NULL)\r
+            break;\r
+        /*\r
+         * Make an additional record for completion domain.\r
+         */\r
+        buflen -= RRFIXEDSZ;\r
+        n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);\r
+        if (n < 0)\r
+            return (-1);\r
+        cp += n;\r
+        buflen -= n;\r
+        __putshort(T_NULL, cp);\r
+        cp += INT16SZ;\r
+        __putshort((u_int16_t)class, cp);\r
+        cp += INT16SZ;\r
+        __putlong(0, cp);\r
+        cp += INT32SZ;\r
+        __putshort(0, cp);\r
+        cp += INT16SZ;\r
+        hp->arcount = htons(1);\r
+        break;\r
+\r
+    case IQUERY:\r
+        /*\r
+         * Initialize answer section\r
+         */\r
+        if (buflen < 1 + RRFIXEDSZ + datalen)\r
+            return (-1);\r
+        *cp++ = '\0';   /* no domain name */\r
+        __putshort((u_int16_t)type, cp);\r
+        cp += INT16SZ;\r
+        __putshort((u_int16_t)class, cp);\r
+        cp += INT16SZ;\r
+        __putlong(0, cp);\r
+        cp += INT32SZ;\r
+        __putshort((u_int16_t)datalen, cp);\r
+        cp += INT16SZ;\r
+        if (datalen) {\r
+            memcpy(cp, data, datalen);\r
+            cp += datalen;\r
+        }\r
+        hp->ancount = htons(1);\r
+        break;\r
+\r
+    default:\r
+        return (-1);\r
+    }\r
+    return ((int)(cp - buf));\r
+}\r
diff --git a/StdLib/BsdSocketLib/res_mkupdate.c b/StdLib/BsdSocketLib/res_mkupdate.c
new file mode 100644 (file)
index 0000000..b27c2e4
--- /dev/null
@@ -0,0 +1,454 @@
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ *\r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Based on the Dynamic DNS reference implementation by Viraj Bais\r
+ * <viraj_bais@ccm.fm.intel.com>\r
+ */\r
+\r
+#if !defined(lint) && !defined(SABER)\r
+static char rcsid[] = "$Id: res_mkupdate.c,v 1.1.1.1 2003/11/19 01:51:38 kyu3 Exp $";\r
+#endif /* not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+\r
+#include <netinet/in.h>\r
+#include <arpa/nameser.h>\r
+#include <arpa/inet.h>\r
+\r
+#include <errno.h>\r
+#include <limits.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <ctype.h>\r
+\r
+#include "res_config.h"\r
+\r
+static int getnum_str(u_char **, u_char *);\r
+static int getword_str(char *, int, u_char **, u_char *);\r
+\r
+#define ShrinkBuffer(x)  if ((buflen -= x) < 0) return (-2);\r
+\r
+/*\r
+ * Form update packets.\r
+ * Returns the size of the resulting packet if no error\r
+ * On error,\r
+ *  returns -1 if error in reading a word/number in rdata\r
+ *         portion for update packets\r
+ *      -2 if length of buffer passed is insufficient\r
+ *      -3 if zone section is not the first section in\r
+ *         the linked list, or section order has a problem\r
+ *      -4 on a number overflow\r
+ *      -5 unknown operation or no records\r
+ */\r
+int\r
+res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {\r
+    ns_updrec *rrecp_start = rrecp_in;\r
+    HEADER *hp;\r
+    u_char *cp, *sp1, *sp2, *startp, *endp;\r
+    int n, i, soanum, multiline;\r
+    ns_updrec *rrecp;\r
+    struct in_addr ina;\r
+        char buf2[MAXDNAME];\r
+    int section, numrrs = 0, counts[ns_s_max];\r
+    u_int16_t rtype, rclass;\r
+    u_int32_t n1, rttl;\r
+    u_char *dnptrs[20], **dpp, **lastdnptr;\r
+\r
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+        h_errno = NETDB_INTERNAL;\r
+        return (-1);\r
+    }\r
+\r
+    /*\r
+     * Initialize header fields.\r
+     */\r
+    if ((buf == NULL) || (buflen < HFIXEDSZ))\r
+        return (-1);\r
+    memset(buf, 0, HFIXEDSZ);\r
+    hp = (HEADER *) buf;\r
+    hp->id = htons(++_res.id);\r
+    hp->opcode = ns_o_update;\r
+    hp->rcode = NOERROR;\r
+    sp1 = buf + 2*INT16SZ;  /* save pointer to zocount */\r
+    cp = buf + HFIXEDSZ;\r
+    buflen -= HFIXEDSZ;\r
+    dpp = dnptrs;\r
+    *dpp++ = buf;\r
+    *dpp++ = NULL;\r
+    lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];\r
+\r
+    if (rrecp_start == NULL)\r
+        return (-5);\r
+    else if (rrecp_start->r_section != S_ZONE)\r
+        return (-3);\r
+\r
+    memset(counts, 0, sizeof counts);\r
+    for (rrecp = rrecp_start; rrecp; rrecp = rrecp->r_grpnext) {\r
+        numrrs++;\r
+                section = rrecp->r_section;\r
+        if (section < 0 || section >= ns_s_max)\r
+            return (-1);\r
+        counts[section]++;\r
+        for (i = section + 1; i < ns_s_max; i++)\r
+            if (counts[i])\r
+                return (-3);\r
+        rtype = rrecp->r_type;\r
+        rclass = rrecp->r_class;\r
+        rttl = rrecp->r_ttl;\r
+        /* overload class and type */\r
+        if (section == S_PREREQ) {\r
+            rttl = 0;\r
+            switch (rrecp->r_opcode) {\r
+            case YXDOMAIN:\r
+                rclass = C_ANY;\r
+                rtype = T_ANY;\r
+                rrecp->r_size = 0;\r
+                break;\r
+            case NXDOMAIN:\r
+                rclass = C_NONE;\r
+                rtype = T_ANY;\r
+                rrecp->r_size = 0;\r
+                break;\r
+            case NXRRSET:\r
+                rclass = C_NONE;\r
+                rrecp->r_size = 0;\r
+                break;\r
+            case YXRRSET:\r
+                if (rrecp->r_size == 0)\r
+                    rclass = C_ANY;\r
+                break;\r
+            default:\r
+                fprintf(stderr,\r
+                    "res_mkupdate: incorrect opcode: %d\n",\r
+                    rrecp->r_opcode);\r
+                fflush(stderr);\r
+                return (-1);\r
+            }\r
+        } else if (section == S_UPDATE) {\r
+            switch (rrecp->r_opcode) {\r
+            case DELETE:\r
+                rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;\r
+                break;\r
+            case ADD:\r
+                break;\r
+            default:\r
+                fprintf(stderr,\r
+                    "res_mkupdate: incorrect opcode: %d\n",\r
+                    rrecp->r_opcode);\r
+                fflush(stderr);\r
+                return (-1);\r
+            }\r
+        }\r
+\r
+        /*\r
+         * XXX  appending default domain to owner name is omitted,\r
+         *  fqdn must be provided\r
+         */\r
+        if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,\r
+                 lastdnptr)) < 0)\r
+            return (-1);\r
+        cp += n;\r
+        ShrinkBuffer(n + 2*INT16SZ);\r
+        PUTSHORT(rtype, cp);\r
+        PUTSHORT(rclass, cp);\r
+        if (section == S_ZONE) {\r
+            if (numrrs != 1 || rrecp->r_type != T_SOA)\r
+                return (-3);\r
+            continue;\r
+        }\r
+        ShrinkBuffer(INT32SZ + INT16SZ);\r
+        PUTLONG(rttl, cp);\r
+        sp2 = cp;  /* save pointer to length byte */\r
+        cp += INT16SZ;\r
+        if (rrecp->r_size == 0) {\r
+            if (section == S_UPDATE && rclass != C_ANY)\r
+                return (-1);\r
+            else {\r
+                PUTSHORT(0, sp2);\r
+                continue;\r
+            }\r
+        }\r
+        startp = rrecp->r_data;\r
+        endp = startp + rrecp->r_size - 1;\r
+        /* XXX this should be done centrally. */\r
+        switch (rrecp->r_type) {\r
+        case T_A:\r
+            if (!getword_str(buf2, sizeof buf2, &startp, endp))\r
+                return (-1);\r
+            if (!inet_aton(buf2, &ina))\r
+                return (-1);\r
+            n1 = ntohl(ina.s_addr);\r
+            ShrinkBuffer(INT32SZ);\r
+            PUTLONG(n1, cp);\r
+            break;\r
+        case T_CNAME:\r
+        case T_MB:\r
+        case T_MG:\r
+        case T_MR:\r
+        case T_NS:\r
+        case T_PTR:\r
+            if (!getword_str(buf2, sizeof buf2, &startp, endp))\r
+                return (-1);\r
+            n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);\r
+            if (n < 0)\r
+                return (-1);\r
+            cp += n;\r
+            ShrinkBuffer(n);\r
+            break;\r
+        case T_MINFO:\r
+        case T_SOA:\r
+        case T_RP:\r
+            for (i = 0; i < 2; i++) {\r
+                if (!getword_str(buf2, sizeof buf2, &startp,\r
+                         endp))\r
+                return (-1);\r
+                n = dn_comp(buf2, cp, buflen,\r
+                        dnptrs, lastdnptr);\r
+                if (n < 0)\r
+                    return (-1);\r
+                cp += n;\r
+                ShrinkBuffer(n);\r
+            }\r
+            if (rrecp->r_type == T_SOA) {\r
+                ShrinkBuffer(5 * INT32SZ);\r
+                while (isspace(*startp) || !*startp)\r
+                    startp++;\r
+                if (*startp == '(') {\r
+                    multiline = 1;\r
+                    startp++;\r
+                } else\r
+                    multiline = 0;\r
+                /* serial, refresh, retry, expire, minimum */\r
+                for (i = 0; i < 5; i++) {\r
+                    soanum = getnum_str(&startp, endp);\r
+                    if (soanum < 0)\r
+                        return (-1);\r
+                    PUTLONG(soanum, cp);\r
+                }\r
+                if (multiline) {\r
+                    while (isspace(*startp) || !*startp)\r
+                        startp++;\r
+                    if (*startp != ')')\r
+                        return (-1);\r
+                }\r
+            }\r
+            break;\r
+        case T_MX:\r
+        case T_AFSDB:\r
+        case T_RT:\r
+            n = getnum_str(&startp, endp);\r
+            if (n < 0)\r
+                return (-1);\r
+            PUTSHORT(n, cp);\r
+            ShrinkBuffer(INT16SZ);\r
+            if (!getword_str(buf2, sizeof buf2, &startp, endp))\r
+                return (-1);\r
+            n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);\r
+            if (n < 0)\r
+                return (-1);\r
+            cp += n;\r
+            ShrinkBuffer(n);\r
+            break;\r
+        case T_PX:\r
+            n = getnum_str(&startp, endp);\r
+            if (n < 0)\r
+                return (-1);\r
+            PUTSHORT(n, cp);\r
+            ShrinkBuffer(INT16SZ);\r
+            for (i = 0; i < 2; i++) {\r
+                if (!getword_str(buf2, sizeof buf2, &startp,\r
+                         endp))\r
+                    return (-1);\r
+                n = dn_comp(buf2, cp, buflen, dnptrs,\r
+                        lastdnptr);\r
+                if (n < 0)\r
+                    return (-1);\r
+                cp += n;\r
+                ShrinkBuffer(n);\r
+            }\r
+            break;\r
+        case T_WKS:\r
+        case T_HINFO:\r
+        case T_TXT:\r
+        case T_X25:\r
+        case T_ISDN:\r
+        case T_NSAP:\r
+        case T_LOC:\r
+            /* XXX - more fine tuning needed here */\r
+            ShrinkBuffer(rrecp->r_size);\r
+            memcpy(cp, rrecp->r_data, rrecp->r_size);\r
+            cp += rrecp->r_size;\r
+            break;\r
+        default:\r
+            return (-1);\r
+        } /*switch*/\r
+        n = (u_int16_t)((cp - sp2) - INT16SZ);\r
+        PUTSHORT(n, sp2);\r
+    } /*for*/\r
+\r
+    hp->qdcount = htons(counts[0]);\r
+    hp->ancount = htons(counts[1]);\r
+    hp->nscount = htons(counts[2]);\r
+    hp->arcount = htons(counts[3]);\r
+    return ((int)(cp - buf));\r
+}\r
+\r
+/*\r
+ * Get a whitespace delimited word from a string (not file)\r
+ * into buf. modify the start pointer to point after the\r
+ * word in the string.\r
+ */\r
+static int\r
+getword_str(char *buf, int size, u_char **startpp, u_char *endp) {\r
+        char *cp;\r
+        int c;\r
+\r
+        for (cp = buf; *startpp <= endp; ) {\r
+                c = **startpp;\r
+                if (isspace(c) || c == '\0') {\r
+                        if (cp != buf) /* trailing whitespace */\r
+                                break;\r
+                        else { /* leading whitespace */\r
+                                (*startpp)++;\r
+                                continue;\r
+                        }\r
+                }\r
+                (*startpp)++;\r
+                if (cp >= buf+size-1)\r
+                        break;\r
+                *cp++ = (u_char)c;\r
+        }\r
+        *cp = '\0';\r
+        return (cp != buf);\r
+}\r
+\r
+/*\r
+ * Get a whitespace delimited number from a string (not file) into buf\r
+ * update the start pointer to point after the number in the string.\r
+ */\r
+static int\r
+getnum_str(u_char **startpp, u_char *endp) {\r
+        int c;\r
+        int n;\r
+        int seendigit = 0;\r
+        int m = 0;\r
+\r
+        for (n = 0; *startpp <= endp; ) {\r
+                c = **startpp;\r
+                if (isspace(c) || c == '\0') {\r
+                        if (seendigit) /* trailing whitespace */\r
+                                break;\r
+                        else { /* leading whitespace */\r
+                                (*startpp)++;\r
+                                continue;\r
+                        }\r
+                }\r
+                if (c == ';') {\r
+                        while ((*startpp <= endp) &&\r
+                   ((c = **startpp) != '\n'))\r
+                    (*startpp)++;\r
+                        if (seendigit)\r
+                                break;\r
+                        continue;\r
+                }\r
+                if (!isdigit(c)) {\r
+                        if (c == ')' && seendigit) {\r
+                                (*startpp)--;\r
+                                break;\r
+                        }\r
+            return (-1);\r
+                }\r
+                (*startpp)++;\r
+                n = n * 10 + (c - '0');\r
+                seendigit = 1;\r
+        }\r
+        return (n + m);\r
+}\r
+\r
+/*\r
+ * Allocate a resource record buffer & save rr info.\r
+ */\r
+ns_updrec *\r
+res_mkupdrec(int section, const char *dname,\r
+         u_int class, u_int type, u_long ttl) {\r
+    ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec));\r
+\r
+    if (!rrecp || !(rrecp->r_dname = strdup(dname)))\r
+        return (NULL);\r
+    rrecp->r_class = (u_int16_t)class;\r
+    rrecp->r_type = (u_int16_t)type;\r
+    rrecp->r_ttl = (u_int32_t)ttl;\r
+    rrecp->r_section = (u_int8_t)section;\r
+    return (rrecp);\r
+}\r
+\r
+/*\r
+ * Free a resource record buffer created by res_mkupdrec.\r
+ */\r
+void\r
+res_freeupdrec(ns_updrec *rrecp) {\r
+    /* Note: freeing r_dp is the caller's responsibility. */\r
+    if (rrecp->r_dname != NULL)\r
+        free(rrecp->r_dname);\r
+    free(rrecp);\r
+}\r
diff --git a/StdLib/BsdSocketLib/res_query.c b/StdLib/BsdSocketLib/res_query.c
new file mode 100644 (file)
index 0000000..791ff01
--- /dev/null
@@ -0,0 +1,430 @@
+/*\r
+ * Copyright (c) 1988, 1993\r
+ *    The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ *\r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";\r
+static char orig_rcsid = "From: Id: res_query.c,v 8.14 1997/06/09 17:47:05 halley Exp $";\r
+static char rcsid[] = "$Id: res_query.c,v 1.1.1.1 2003/11/19 01:51:38 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+#include <ctype.h>\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include "res_config.h"\r
+\r
+#if PACKETSZ > 1024\r
+#define MAXPACKET   PACKETSZ\r
+#else\r
+#define MAXPACKET   1024\r
+#endif\r
+\r
+/*\r
+ * Formulate a normal query, send, and await answer.\r
+ * Returned answer is placed in supplied buffer "answer".\r
+ * Perform preliminary check of answer, returning success only\r
+ * if no error is indicated and the answer count is nonzero.\r
+ * Return the size of the response on success, -1 on error.\r
+ * Error number is left in h_errno.\r
+ *\r
+ * Caller must parse answer and determine whether it answers the question.\r
+ */\r
+int\r
+res_query(\r
+    const char *name,   /* domain name */\r
+    int class,          /* class of query */\r
+    int type,           /* type of query */\r
+    u_char *answer,     /* buffer to put answer */\r
+    int anslen          /* size of answer buffer */\r
+    )\r
+{\r
+    u_char buf[MAXPACKET];\r
+    HEADER *hp = (HEADER *) answer;\r
+    int n;\r
+\r
+    hp->rcode = NOERROR;    /* default */\r
+\r
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+        h_errno = NETDB_INTERNAL;\r
+        return (-1);\r
+    }\r
+#ifdef DEBUG\r
+    if (_res.options & RES_DEBUG)\r
+        printf(";; res_query(%s, %d, %d)\n", name, class, type);\r
+#endif\r
+\r
+    n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,\r
+            buf, sizeof(buf));\r
+    if (n <= 0) {\r
+#ifdef DEBUG\r
+        if (_res.options & RES_DEBUG)\r
+            printf(";; res_query: mkquery failed\n");\r
+#endif\r
+        h_errno = NO_RECOVERY;\r
+        return (n);\r
+    }\r
+    n = res_send(buf, n, answer, anslen);\r
+    if (n < 0) {\r
+#ifdef DEBUG\r
+        if (_res.options & RES_DEBUG)\r
+            printf(";; res_query: send error\n");\r
+#endif\r
+        h_errno = TRY_AGAIN;\r
+        return (n);\r
+    }\r
+\r
+    if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {\r
+#ifdef DEBUG\r
+        if (_res.options & RES_DEBUG)\r
+            printf(";; rcode = %d, ancount=%d\n", hp->rcode,\r
+                ntohs(hp->ancount));\r
+#endif\r
+        switch (hp->rcode) {\r
+        case NXDOMAIN:\r
+            h_errno = HOST_NOT_FOUND;\r
+            break;\r
+        case SERVFAIL:\r
+            h_errno = TRY_AGAIN;\r
+            break;\r
+        case NOERROR:\r
+            h_errno = NO_DATA;\r
+            break;\r
+        case FORMERR:\r
+        case NOTIMP:\r
+        case REFUSED:\r
+        default:\r
+            h_errno = NO_RECOVERY;\r
+            break;\r
+        }\r
+        return (-1);\r
+    }\r
+    return (n);\r
+}\r
+\r
+/*\r
+ * Formulate a normal query, send, and retrieve answer in supplied buffer.\r
+ * Return the size of the response on success, -1 on error.\r
+ * If enabled, implement search rules until answer or unrecoverable failure\r
+ * is detected.  Error code, if any, is left in h_errno.\r
+ */\r
+int\r
+res_search(\r
+    const char *name,   /* domain name */\r
+    int class,          /* class of query */\r
+    int type,           /* type of query */\r
+    u_char *answer,     /* buffer to put answer */\r
+    int anslen          /* size of answer */\r
+    )\r
+{\r
+    const char *cp, * const *domain;\r
+    HEADER *hp = (HEADER *) answer;\r
+    u_int dots;\r
+    int trailing_dot, ret, saved_herrno;\r
+    int got_nodata = 0, got_servfail = 0, tried_as_is = 0;\r
+\r
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+        h_errno = NETDB_INTERNAL;\r
+        return (-1);\r
+    }\r
+    errno = 0;\r
+    h_errno = HOST_NOT_FOUND;   /* default, if we never query */\r
+    dots = 0;\r
+    for (cp = name; *cp; cp++)\r
+        dots += (*cp == '.');\r
+    trailing_dot = 0;\r
+    if (cp > name && *--cp == '.')\r
+        trailing_dot++;\r
+\r
+    /* If there aren't any dots, it could be a user-level alias */\r
+    if (!dots && (cp = hostalias(name)) != NULL)\r
+        return (res_query(cp, class, type, answer, anslen));\r
+\r
+    /*\r
+     * If there are dots in the name already, let's just give it a try\r
+     * 'as is'.  The threshold can be set with the "ndots" option.\r
+     */\r
+    saved_herrno = -1;\r
+    if (dots >= _res.ndots) {\r
+        ret = res_querydomain(name, NULL, class, type, answer, anslen);\r
+        if (ret > 0)\r
+            return (ret);\r
+        saved_herrno = h_errno;\r
+        tried_as_is++;\r
+    }\r
+\r
+    /*\r
+     * We do at least one level of search if\r
+     *  - there is no dot and RES_DEFNAME is set, or\r
+     *  - there is at least one dot, there is no trailing dot,\r
+     *    and RES_DNSRCH is set.\r
+     */\r
+    if ((!dots && (_res.options & RES_DEFNAMES)) ||\r
+        (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {\r
+        int done = 0;\r
+\r
+        for (domain = (const char * const *)_res.dnsrch;\r
+             *domain && !done;\r
+             domain++) {\r
+\r
+            ret = res_querydomain(name, *domain, class, type,\r
+                          answer, anslen);\r
+            if (ret > 0)\r
+                return (ret);\r
+\r
+            /*\r
+             * If no server present, give up.\r
+             * If name isn't found in this domain,\r
+             * keep trying higher domains in the search list\r
+             * (if that's enabled).\r
+             * On a NO_DATA error, keep trying, otherwise\r
+             * a wildcard entry of another type could keep us\r
+             * from finding this entry higher in the domain.\r
+             * If we get some other error (negative answer or\r
+             * server failure), then stop searching up,\r
+             * but try the input name below in case it's\r
+             * fully-qualified.\r
+             */\r
+            if (errno == ECONNREFUSED) {\r
+                h_errno = TRY_AGAIN;\r
+                return (-1);\r
+            }\r
+\r
+            switch (h_errno) {\r
+            case NO_DATA:\r
+                got_nodata++;\r
+                /* FALLTHROUGH */\r
+            case HOST_NOT_FOUND:\r
+                /* keep trying */\r
+                break;\r
+            case TRY_AGAIN:\r
+                if (hp->rcode == SERVFAIL) {\r
+                    /* try next search element, if any */\r
+                    got_servfail++;\r
+                    break;\r
+                }\r
+                /* FALLTHROUGH */\r
+            default:\r
+                /* anything else implies that we're done */\r
+                done++;\r
+            }\r
+\r
+            /* if we got here for some reason other than DNSRCH,\r
+             * we only wanted one iteration of the loop, so stop.\r
+             */\r
+            if (!(_res.options & RES_DNSRCH))\r
+                done++;\r
+        }\r
+    }\r
+\r
+    /*\r
+     * If we have not already tried the name "as is", do that now.\r
+     * note that we do this regardless of how many dots were in the\r
+     * name or whether it ends with a dot unless NOTLDQUERY is set.\r
+     */\r
+    if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {\r
+        ret = res_querydomain(name, NULL, class, type, answer, anslen);\r
+        if (ret > 0)\r
+            return (ret);\r
+    }\r
+\r
+    /* if we got here, we didn't satisfy the search.\r
+     * if we did an initial full query, return that query's h_errno\r
+     * (note that we wouldn't be here if that query had succeeded).\r
+     * else if we ever got a nodata, send that back as the reason.\r
+     * else send back meaningless h_errno, that being the one from\r
+     * the last DNSRCH we did.\r
+     */\r
+    if (saved_herrno != -1)\r
+        h_errno = saved_herrno;\r
+    else if (got_nodata)\r
+        h_errno = NO_DATA;\r
+    else if (got_servfail)\r
+        h_errno = TRY_AGAIN;\r
+    return (-1);\r
+}\r
+\r
+/*\r
+ * Perform a call on res_query on the concatenation of name and domain,\r
+ * removing a trailing dot from name if domain is NULL.\r
+ */\r
+int\r
+res_querydomain(\r
+    const char *name,\r
+    const char *domain,\r
+    int class,      /* class of query */\r
+    int type,       /* type of query */\r
+    u_char *answer, /* buffer to put answer */\r
+    int anslen      /* size of answer */\r
+    )\r
+{\r
+    char nbuf[MAXDNAME];\r
+    const char *longname = nbuf;\r
+    int n, d;\r
+\r
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+        h_errno = NETDB_INTERNAL;\r
+        return (-1);\r
+    }\r
+#ifdef DEBUG\r
+    if (_res.options & RES_DEBUG)\r
+        printf(";; res_querydomain(%s, %s, %d, %d)\n",\r
+               name, domain?domain:"<Nil>", class, type);\r
+#endif\r
+    if (domain == NULL) {\r
+        /*\r
+         * Check for trailing '.';\r
+         * copy without '.' if present.\r
+         */\r
+        n = (int)strlen(name);\r
+        if (n >= MAXDNAME) {\r
+            h_errno = NO_RECOVERY;\r
+            return (-1);\r
+        }\r
+        n--;\r
+        if (n >= 0 && name[n] == '.') {\r
+            strncpy(nbuf, name, n);\r
+            nbuf[n] = '\0';\r
+        } else\r
+            longname = name;\r
+    } else {\r
+        n = (int)strlen(name);\r
+        d = (int)strlen(domain);\r
+        if (n + d + 1 >= MAXDNAME) {\r
+            h_errno = NO_RECOVERY;\r
+            return (-1);\r
+        }\r
+        sprintf(nbuf, "%s.%s", name, domain);\r
+    }\r
+    return (res_query(longname, class, type, answer, anslen));\r
+}\r
+\r
+const char *\r
+hostalias(\r
+    const char *name\r
+    )\r
+{\r
+    register char *cp1, *cp2;\r
+    FILE *fp;\r
+    char *file;\r
+    char buf[BUFSIZ];\r
+    static char abuf[MAXDNAME];\r
+\r
+    if (_res.options & RES_NOALIASES)\r
+        return (NULL);\r
+#ifdef _ORG_FREEBSD_\r
+    if (issetugid())\r
+        return (NULL);\r
+#endif\r
+    file = getenv("HOSTALIASES");\r
+    if (file == NULL || (fp = fopen(file, "r")) == NULL)\r
+        return (NULL);\r
+    setbuf(fp, NULL);\r
+    buf[sizeof(buf) - 1] = '\0';\r
+    while (fgets(buf, sizeof(buf), fp)) {\r
+        for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)\r
+            ;\r
+        if (!*cp1)\r
+            break;\r
+        *cp1 = '\0';\r
+        if (!strcasecmp(buf, name)) {\r
+            while (isspace(*++cp1))\r
+                ;\r
+            if (!*cp1)\r
+                break;\r
+            for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)\r
+                ;\r
+            abuf[sizeof(abuf) - 1] = *cp2 = '\0';\r
+            strncpy(abuf, cp1, sizeof(abuf) - 1);\r
+            fclose(fp);\r
+            return (abuf);\r
+        }\r
+    }\r
+    fclose(fp);\r
+    return (NULL);\r
+}\r
diff --git a/StdLib/BsdSocketLib/res_send.c b/StdLib/BsdSocketLib/res_send.c
new file mode 100644 (file)
index 0000000..82addc9
--- /dev/null
@@ -0,0 +1,934 @@
+/*\r
+ * Copyright (c) 1985, 1989, 1993\r
+ *    The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ *\r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies, and that\r
+ * the name of Digital Equipment Corporation not be used in advertising or\r
+ * publicity pertaining to distribution of the document or software without\r
+ * specific, written prior permission.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\r
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)res_send.c  8.1 (Berkeley) 6/4/93";\r
+static char orig_rcsid[] = "From: Id: res_send.c,v 8.20 1998/04/06 23:27:51 halley Exp $";\r
+static char rcsid[] = "$Id: res_send.c,v 1.1.1.1 2003/11/19 01:51:39 kyu3 Exp $";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+/*\r
+ * Send query to name server and wait for reply.\r
+ */\r
+\r
+#include <sys/types.h>\r
+#include <sys/param.h>\r
+#include <sys/select.h>\r
+#include <sys/socket.h>\r
+#include <sys/time.h>\r
+#include <sys/uio.h>\r
+\r
+#include <netinet/in.h>\r
+#include <arpa/nameser.h>\r
+#include <arpa/inet.h>\r
+\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+\r
+#include "res_config.h"\r
+\r
+#ifndef _ORG_FREEBSD_\r
+#define NOPOLL\r
+#endif\r
+\r
+#ifdef NOPOLL           /* libc_r doesn't wrap poll yet() */\r
+static int use_poll = 0;\r
+#else\r
+#include <poll.h>\r
+static int use_poll = 1;    /* adapt to poll() syscall availability */\r
+                /* 0 = not present, 1 = try it, 2 = exists */\r
+#endif\r
+\r
+static int s = -1;      /* socket used for communications */\r
+static int connected = 0;   /* is the socket connected */\r
+static int vc = 0;      /* is the socket a virtual circuit? */\r
+static res_send_qhook Qhook = NULL;\r
+static res_send_rhook Rhook = NULL;\r
+\r
+\r
+#define CAN_RECONNECT 1\r
+\r
+#ifndef DEBUG\r
+#   define Dprint(cond, args) /*empty*/\r
+#   define DprintQ(cond, args, query, size) /*empty*/\r
+#   define Aerror(file, string, error, address) /*empty*/\r
+#   define Perror(file, string, error) /*empty*/\r
+#else\r
+#   define Dprint(cond, args) if (cond) {fprintf args;} else {}\r
+#   define DprintQ(cond, args, query, size) if (cond) {\\r
+            fprintf args;\\r
+            __fp_nquery(query, size, stdout);\\r
+        } else {}\r
+\r
+static void\r
+Aerror(\r
+    FILE *file,\r
+    char *string,\r
+    int error,\r
+    struct sockaddr_in address\r
+    )\r
+{\r
+    int save = errno;\r
+\r
+    if (_res.options & RES_DEBUG) {\r
+        fprintf(file, "res_send: %s ([%s].%u): %s\n",\r
+            string,\r
+            inet_ntoa(address.sin_addr),\r
+            ntohs(address.sin_port),\r
+            strerror(error));\r
+    }\r
+    errno = save;\r
+}\r
+\r
+\r
+static void\r
+Perror(\r
+    FILE *file,\r
+    char *string,\r
+    int error\r
+    )\r
+{\r
+    int save = errno;\r
+\r
+    if (_res.options & RES_DEBUG) {\r
+        fprintf(file, "res_send: %s: %s\n",\r
+            string, strerror(error));\r
+    }\r
+    errno = save;\r
+}\r
+#endif\r
+\r
+void\r
+res_send_setqhook(\r
+    res_send_qhook hook\r
+    )\r
+{\r
+\r
+    Qhook = hook;\r
+}\r
+\r
+void\r
+res_send_setrhook(\r
+    res_send_rhook hook\r
+    )\r
+{\r
+\r
+    Rhook = hook;\r
+}\r
+\r
+/* int\r
+ * res_isourserver(ina)\r
+ *  looks up "ina" in _res.ns_addr_list[]\r
+ * returns:\r
+ *  0  : not found\r
+ *  >0 : found\r
+ * author:\r
+ *  paul vixie, 29may94\r
+ */\r
+int\r
+res_isourserver(\r
+    const struct sockaddr_in *inp\r
+    )\r
+{\r
+    struct sockaddr_in ina;\r
+    int ns, ret;\r
+\r
+    ina = *inp;\r
+    ret = 0;\r
+    for (ns = 0;  ns < _res.nscount;  ns++) {\r
+        const struct sockaddr_in *srv = &_res.nsaddr_list[ns];\r
+\r
+        if (srv->sin_family == ina.sin_family &&\r
+            srv->sin_port == ina.sin_port &&\r
+            (srv->sin_addr.s_addr == INADDR_ANY ||\r
+             srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {\r
+            ret++;\r
+            break;\r
+        }\r
+    }\r
+    return (ret);\r
+}\r
+\r
+/* int\r
+ * res_nameinquery(name, type, class, buf, eom)\r
+ *  look for (name,type,class) in the query section of packet (buf,eom)\r
+ * requires:\r
+ *  buf + HFIXEDSZ <= eom\r
+ * returns:\r
+ *  -1 : format error\r
+ *  0  : not found\r
+ *  >0 : found\r
+ * author:\r
+ *  paul vixie, 29may94\r
+ */\r
+int\r
+res_nameinquery(\r
+    const char *name,\r
+    int type,\r
+    int class,\r
+    const u_char *buf,\r
+    const u_char *eom\r
+    )\r
+{\r
+    const u_char *cp = buf + HFIXEDSZ;\r
+    int qdcount = ntohs(((HEADER*)buf)->qdcount);\r
+\r
+    while (qdcount-- > 0) {\r
+        char tname[MAXDNAME+1];\r
+        int n, ttype, tclass;\r
+\r
+        n = dn_expand(buf, eom, cp, tname, sizeof tname);\r
+        if (n < 0)\r
+            return (-1);\r
+        cp += n;\r
+        if (cp + 2 * INT16SZ > eom)\r
+            return (-1);\r
+        ttype = ns_get16(cp); cp += INT16SZ;\r
+        tclass = ns_get16(cp); cp += INT16SZ;\r
+        if (ttype == type &&\r
+            tclass == class &&\r
+            strcasecmp(tname, name) == 0)\r
+            return (1);\r
+    }\r
+    return (0);\r
+}\r
+\r
+/* int\r
+ * res_queriesmatch(buf1, eom1, buf2, eom2)\r
+ *  is there a 1:1 mapping of (name,type,class)\r
+ *  in (buf1,eom1) and (buf2,eom2)?\r
+ * returns:\r
+ *  -1 : format error\r
+ *  0  : not a 1:1 mapping\r
+ *  >0 : is a 1:1 mapping\r
+ * author:\r
+ *  paul vixie, 29may94\r
+ */\r
+int\r
+res_queriesmatch(\r
+    const u_char *buf1,\r
+    const u_char *eom1,\r
+    const u_char *buf2,\r
+    const u_char *eom2\r
+    )\r
+{\r
+    const u_char *cp = buf1 + HFIXEDSZ;\r
+    int qdcount = ntohs(((HEADER*)buf1)->qdcount);\r
+\r
+    if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)\r
+        return (-1);\r
+\r
+    /*\r
+     * Only header section present in replies to\r
+     * dynamic update packets.\r
+     */\r
+    if ( (((HEADER *)buf1)->opcode == ns_o_update) &&\r
+         (((HEADER *)buf2)->opcode == ns_o_update) )\r
+        return (1);\r
+\r
+    if (qdcount != ntohs(((HEADER*)buf2)->qdcount))\r
+        return (0);\r
+    while (qdcount-- > 0) {\r
+        char tname[MAXDNAME+1];\r
+        int n, ttype, tclass;\r
+\r
+        n = dn_expand(buf1, eom1, cp, tname, sizeof tname);\r
+        if (n < 0)\r
+            return (-1);\r
+        cp += n;\r
+        if (cp + 2 * INT16SZ > eom1)\r
+            return (-1);\r
+        ttype = ns_get16(cp);   cp += INT16SZ;\r
+        tclass = ns_get16(cp); cp += INT16SZ;\r
+        if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))\r
+            return (0);\r
+    }\r
+    return (1);\r
+}\r
+\r
+int\r
+res_send(\r
+    const u_char *buf,\r
+    int buflen,\r
+    u_char *ans,\r
+    int anssiz\r
+    )\r
+{\r
+    HEADER *hp = (HEADER *) buf;\r
+    HEADER *anhp = (HEADER *) ans;\r
+    int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;\r
+    ssize_t n;\r
+    u_int32_t badns;    /* XXX NSMAX can't exceed #/bits in this variable */\r
+\r
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+        /* errno should have been set by res_init() in this case. */\r
+        return (-1);\r
+    }\r
+    if (anssiz < HFIXEDSZ) {\r
+        errno = EINVAL;\r
+        return (-1);\r
+    }\r
+    DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),\r
+        (stdout, ";; res_send()\n"), buf, buflen);\r
+    v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;\r
+    gotsomewhere = 0;\r
+    connreset = 0;\r
+    terrno = ETIMEDOUT;\r
+    badns = 0;\r
+\r
+    /*\r
+     * Send request, RETRY times, or until successful\r
+     */\r
+    for (try = 0; try < _res.retry; try++) {\r
+        for (ns = 0; ns < _res.nscount; ns++) {\r
+        struct sockaddr_in *nsap = &_res.nsaddr_list[ns];\r
+    same_ns:\r
+        if (badns & (1 << ns)) {\r
+            res_close();\r
+            goto next_ns;\r
+        }\r
+\r
+        if (Qhook) {\r
+            int done = 0, loops = 0;\r
+\r
+            do {\r
+                res_sendhookact act;\r
+\r
+                act = (*Qhook)(&nsap, &buf, &buflen,\r
+                           ans, anssiz, &resplen);\r
+                switch (act) {\r
+                case res_goahead:\r
+                    done = 1;\r
+                    break;\r
+                case res_nextns:\r
+                    res_close();\r
+                    goto next_ns;\r
+                case res_done:\r
+                    return (resplen);\r
+                case res_modified:\r
+                    /* give the hook another try */\r
+                    if (++loops < 42) /*doug adams*/\r
+                        break;\r
+                    /*FALLTHROUGH*/\r
+                case res_error:\r
+                    /*FALLTHROUGH*/\r
+                default:\r
+                    return (-1);\r
+                }\r
+            } while (!done);\r
+        }\r
+\r
+        Dprint(_res.options & RES_DEBUG,\r
+               (stdout, ";; Querying server (# %d) address = %s\n",\r
+            ns + 1, inet_ntoa(nsap->sin_addr)));\r
+\r
+        if (v_circuit) {\r
+            int truncated;\r
+            struct iovec iov[2];\r
+            u_short len;\r
+            u_char *cp;\r
+\r
+            /*\r
+             * Use virtual circuit;\r
+             * at most one attempt per server.\r
+             */\r
+            try = _res.retry;\r
+            truncated = 0;\r
+            if (s < 0 || !vc || hp->opcode == ns_o_update) {\r
+                if (s >= 0)\r
+                    res_close();\r
+\r
+                s = socket(PF_INET, SOCK_STREAM, 0);\r
+                if (s < 0) {\r
+                    terrno = errno;\r
+                    Perror(stderr, "socket(vc)", errno);\r
+                    return (-1);\r
+                }\r
+                errno = 0;\r
+                nsap->sin_len = sizeof ( *nsap );\r
+                if (connect(s, (struct sockaddr *)nsap,\r
+                        sizeof *nsap) < 0) {\r
+                    terrno = errno;\r
+                    Aerror(stderr, "connect/vc",\r
+                           errno, *nsap);\r
+                    badns |= (1 << ns);\r
+                    res_close();\r
+                    goto next_ns;\r
+                }\r
+                vc = 1;\r
+            }\r
+            /*\r
+             * Send length & message\r
+             */\r
+            putshort((u_short)buflen, (u_char*)&len);\r
+            iov[0].iov_base = (caddr_t)&len;\r
+            iov[0].iov_len = INT16SZ;\r
+            iov[1].iov_base = (caddr_t)buf;\r
+            iov[1].iov_len = buflen;\r
+            if (writev(s, iov, 2) != (INT16SZ + buflen)) {\r
+                terrno = errno;\r
+                Perror(stderr, "write failed", errno);\r
+                badns |= (1 << ns);\r
+                res_close();\r
+                goto next_ns;\r
+            }\r
+            /*\r
+             * Receive length & response\r
+             */\r
+read_len:\r
+            cp = ans;\r
+            len = INT16SZ;\r
+            while ((n = read(s, (char *)cp, (int)len)) > 0) {\r
+                cp += n;\r
+                len = (u_short)( len - n );\r
+                if (len <= 0)\r
+                    break;\r
+            }\r
+            if (n <= 0) {\r
+                terrno = errno;\r
+                Perror(stderr, "read failed", errno);\r
+                res_close();\r
+                /*\r
+                 * A long running process might get its TCP\r
+                 * connection reset if the remote server was\r
+                 * restarted.  Requery the server instead of\r
+                 * trying a new one.  When there is only one\r
+                 * server, this means that a query might work\r
+                 * instead of failing.  We only allow one reset\r
+                 * per query to prevent looping.\r
+                 */\r
+                if (terrno == ECONNRESET && !connreset) {\r
+                    connreset = 1;\r
+                    res_close();\r
+                    goto same_ns;\r
+                }\r
+                res_close();\r
+                goto next_ns;\r
+            }\r
+            resplen = ns_get16(ans);\r
+            if (resplen > anssiz) {\r
+                Dprint(_res.options & RES_DEBUG,\r
+                       (stdout, ";; response truncated\n")\r
+                       );\r
+                truncated = 1;\r
+                len = (ushort)anssiz;\r
+            } else\r
+                len = (ushort)resplen;\r
+            if (len < HFIXEDSZ) {\r
+                /*\r
+                 * Undersized message.\r
+                 */\r
+                Dprint(_res.options & RES_DEBUG,\r
+                       (stdout, ";; undersized: %d\n", len));\r
+                terrno = EMSGSIZE;\r
+                badns |= (1 << ns);\r
+                res_close();\r
+                goto next_ns;\r
+            }\r
+            cp = ans;\r
+            while (len != 0 &&\r
+                   (n = read(s, (char *)cp, (int)len)) > 0) {\r
+                cp += n;\r
+                len = (u_short)( len - n );\r
+            }\r
+            if (n <= 0) {\r
+                terrno = errno;\r
+                Perror(stderr, "read(vc)", errno);\r
+                res_close();\r
+                goto next_ns;\r
+            }\r
+            if (truncated) {\r
+                /*\r
+                 * Flush rest of answer\r
+                 * so connection stays in synch.\r
+                 */\r
+                anhp->tc = 1;\r
+                len = (ushort)( resplen - anssiz );\r
+                while (len != 0) {\r
+                    char junk[PACKETSZ];\r
+\r
+                    n = (len > sizeof(junk)\r
+                         ? sizeof(junk)\r
+                         : len);\r
+                    if ((n = read(s, junk, n)) > 0)\r
+                        len = (u_short)( len - n );\r
+                    else\r
+                        break;\r
+                }\r
+            }\r
+            /*\r
+             * The calling applicating has bailed out of\r
+             * a previous call and failed to arrange to have\r
+             * the circuit closed or the server has got\r
+             * itself confused. Anyway drop the packet and\r
+             * wait for the correct one.\r
+             */\r
+            if (hp->id != anhp->id) {\r
+                DprintQ((_res.options & RES_DEBUG) ||\r
+                    (_res.pfcode & RES_PRF_REPLY),\r
+                    (stdout, ";; old answer (unexpected):\n"),\r
+                    ans, (resplen>anssiz)?anssiz:resplen);\r
+                goto read_len;\r
+            }\r
+        } else {\r
+            /*\r
+             * Use datagrams.\r
+             */\r
+#ifndef NOPOLL\r
+            struct pollfd pfd;\r
+            int msec;\r
+#endif\r
+            struct timeval timeout;\r
+            fd_set dsmask, *dsmaskp;\r
+            int dsmasklen;\r
+            struct sockaddr_in from;\r
+            int fromlen;\r
+\r
+            if ((s < 0) || vc) {\r
+                if (vc)\r
+                    res_close();\r
+                s = socket(PF_INET, SOCK_DGRAM, 0);\r
+                if (s < 0) {\r
+#ifndef CAN_RECONNECT\r
+ bad_dg_sock:\r
+#endif\r
+                    terrno = errno;\r
+                    Perror(stderr, "socket(dg)", errno);\r
+                    return (-1);\r
+                }\r
+                connected = 0;\r
+            }\r
+#ifndef CANNOT_CONNECT_DGRAM\r
+            /*\r
+             * On a 4.3BSD+ machine (client and server,\r
+             * actually), sending to a nameserver datagram\r
+             * port with no nameserver will cause an\r
+             * ICMP port unreachable message to be returned.\r
+             * If our datagram socket is "connected" to the\r
+             * server, we get an ECONNREFUSED error on the next\r
+             * socket operation, and select returns if the\r
+             * error message is received.  We can thus detect\r
+             * the absence of a nameserver without timing out.\r
+             * If we have sent queries to at least two servers,\r
+             * however, we don't want to remain connected,\r
+             * as we wish to receive answers from the first\r
+             * server to respond.\r
+             */\r
+            if (_res.nscount == 1 || (try == 0 && ns == 0)) {\r
+                /*\r
+                 * Connect only if we are sure we won't\r
+                 * receive a response from another server.\r
+                 */\r
+                if (!connected) {\r
+                    nsap->sin_len = sizeof ( *nsap );\r
+                    if (connect(s, (struct sockaddr *)nsap,\r
+                            sizeof *nsap\r
+                            ) < 0) {\r
+                        Aerror(stderr,\r
+                               "connect(dg)",\r
+                               errno, *nsap);\r
+                        badns |= (1 << ns);\r
+                        res_close();\r
+                        goto next_ns;\r
+                    }\r
+                    connected = 1;\r
+                }\r
+                if (send(s, (char*)buf, buflen, 0) != buflen) {\r
+                    Perror(stderr, "send", errno);\r
+                    badns |= (1 << ns);\r
+                    res_close();\r
+                    goto next_ns;\r
+                }\r
+            } else {\r
+                /*\r
+                 * Disconnect if we want to listen\r
+                 * for responses from more than one server.\r
+                 */\r
+                if (connected) {\r
+#ifdef CAN_RECONNECT\r
+                    struct sockaddr_in no_addr;\r
+\r
+                    no_addr.sin_family = AF_INET;\r
+                    no_addr.sin_addr.s_addr = INADDR_ANY;\r
+                    no_addr.sin_port = 0;\r
+                    (void) connect(s,\r
+                               (struct sockaddr *)\r
+                                &no_addr,\r
+                               sizeof no_addr);\r
+#else\r
+                    int s1 = socket(PF_INET, SOCK_DGRAM,0);\r
+                    if (s1 < 0)\r
+                        goto bad_dg_sock;\r
+                    (void) dup2(s1, s);\r
+                    (void) close(s1);\r
+                    Dprint(_res.options & RES_DEBUG,\r
+                        (stdout, ";; new DG socket\n"))\r
+#endif /* CAN_RECONNECT */\r
+                    connected = 0;\r
+                    errno = 0;\r
+                }\r
+#endif /* !CANNOT_CONNECT_DGRAM */\r
+                if (sendto(s, (char*)buf, buflen, 0,\r
+                       (struct sockaddr *)nsap,\r
+                       sizeof *nsap)\r
+                    != buflen) {\r
+                    Aerror(stderr, "sendto", errno, *nsap);\r
+                    badns |= (1 << ns);\r
+                    res_close();\r
+                    goto next_ns;\r
+                }\r
+#ifndef CANNOT_CONNECT_DGRAM\r
+            }\r
+#endif /* !CANNOT_CONNECT_DGRAM */\r
+\r
+            /*\r
+             * Wait for reply\r
+             */\r
+#ifndef NOPOLL\r
+    othersyscall:\r
+            if (use_poll) {\r
+                msec = (_res.retrans << try) * 1000;\r
+                if (try > 0)\r
+                    msec /= _res.nscount;\r
+                if (msec <= 0)\r
+                    msec = 1000;\r
+            } else {\r
+#endif\r
+                timeout.tv_sec = (_res.retrans << try);\r
+                if (try > 0)\r
+                    timeout.tv_sec /= _res.nscount;\r
+                if ((long) timeout.tv_sec <= 0)\r
+                    timeout.tv_sec = 1;\r
+                timeout.tv_usec = 0;\r
+#ifndef NOPOLL\r
+            }\r
+#endif\r
+    wait:\r
+            if (s < 0) {\r
+                Perror(stderr, "s out-of-bounds", EMFILE);\r
+                res_close();\r
+                goto next_ns;\r
+            }\r
+#ifndef NOPOLL\r
+            if (use_poll) {\r
+                struct sigaction sa, osa;\r
+                int sigsys_installed = 0;\r
+\r
+                pfd.fd = s;\r
+                pfd.events = POLLIN;\r
+                if (use_poll == 1) {\r
+                    bzero(&sa, sizeof(sa));\r
+                    sa.sa_handler = SIG_IGN;\r
+                    if (sigaction(SIGSYS, &sa, &osa) >= 0)\r
+                        sigsys_installed = 1;\r
+                }\r
+                n = poll(&pfd, 1, msec);\r
+                if (sigsys_installed == 1) {\r
+                    int oerrno = errno;\r
+                    sigaction(SIGSYS, &osa, NULL);\r
+                    errno = oerrno;\r
+                }\r
+                /* XXX why does nosys() return EINVAL? */\r
+                if (n < 0 && (errno == ENOSYS ||\r
+                    errno == EINVAL)) {\r
+                    use_poll = 0;\r
+                    goto othersyscall;\r
+                } else if (use_poll == 1)\r
+                    use_poll = 2;\r
+                if (n < 0) {\r
+                    if (errno == EINTR)\r
+                        goto wait;\r
+                    Perror(stderr, "poll", errno);\r
+                    res_close();\r
+                    goto next_ns;\r
+                }\r
+            } else {\r
+#endif\r
+                dsmasklen = howmany(s + 1, NFDBITS) *\r
+                        sizeof(fd_mask);\r
+                if (dsmasklen > sizeof(fd_set)) {\r
+                    dsmaskp = (fd_set *)malloc(dsmasklen);\r
+                    if (dsmaskp == NULL) {\r
+                        res_close();\r
+                        goto next_ns;\r
+                    }\r
+                } else\r
+                    dsmaskp = &dsmask;\r
+                /* only zero what we need */\r
+                memset((char *)dsmaskp, 0, dsmasklen);\r
+                FD_SET(s, dsmaskp);\r
+                n = select(s + 1, dsmaskp, (fd_set *)NULL,\r
+                       (fd_set *)NULL, &timeout);\r
+                if (dsmaskp != &dsmask)\r
+                    free(dsmaskp);\r
+                if (n < 0) {\r
+                    if (errno == EINTR)\r
+                        goto wait;\r
+                    Perror(stderr, "select", errno);\r
+                    res_close();\r
+                    goto next_ns;\r
+                }\r
+#ifndef NOPOLL\r
+            }\r
+#endif\r
+\r
+            if (n == 0) {\r
+                /*\r
+                 * timeout\r
+                 */\r
+                Dprint(_res.options & RES_DEBUG,\r
+                       (stdout, ";; timeout\n"));\r
+                gotsomewhere = 1;\r
+                res_close();\r
+                goto next_ns;\r
+            }\r
+            errno = 0;\r
+            fromlen = sizeof(struct sockaddr_in);\r
+            resplen = (int)recvfrom(s, (char*)ans, anssiz, 0,\r
+                       (struct sockaddr *)&from, &fromlen);\r
+            if (resplen <= 0) {\r
+                Perror(stderr, "recvfrom", errno);\r
+                res_close();\r
+                goto next_ns;\r
+            }\r
+            gotsomewhere = 1;\r
+            if (resplen < HFIXEDSZ) {\r
+                /*\r
+                 * Undersized message.\r
+                 */\r
+                Dprint(_res.options & RES_DEBUG,\r
+                       (stdout, ";; undersized: %d\n",\r
+                    resplen));\r
+                terrno = EMSGSIZE;\r
+                badns |= (1 << ns);\r
+                res_close();\r
+                goto next_ns;\r
+            }\r
+            if (hp->id != anhp->id) {\r
+                /*\r
+                 * response from old query, ignore it.\r
+                 * XXX - potential security hazard could\r
+                 *   be detected here.\r
+                 */\r
+                DprintQ((_res.options & RES_DEBUG) ||\r
+                    (_res.pfcode & RES_PRF_REPLY),\r
+                    (stdout, ";; old answer:\n"),\r
+                    ans, (resplen>anssiz)?anssiz:resplen);\r
+                goto wait;\r
+            }\r
+#ifdef CHECK_SRVR_ADDR\r
+            if (!(_res.options & RES_INSECURE1) &&\r
+                !res_isourserver(&from)) {\r
+                /*\r
+                 * response from wrong server? ignore it.\r
+                 * XXX - potential security hazard could\r
+                 *   be detected here.\r
+                 */\r
+                DprintQ((_res.options & RES_DEBUG) ||\r
+                    (_res.pfcode & RES_PRF_REPLY),\r
+                    (stdout, ";; not our server:\n"),\r
+                    ans, (resplen>anssiz)?anssiz:resplen);\r
+                goto wait;\r
+            }\r
+#endif\r
+            if (!(_res.options & RES_INSECURE2) &&\r
+                !res_queriesmatch(buf, buf + buflen,\r
+                          ans, ans + anssiz)) {\r
+                /*\r
+                 * response contains wrong query? ignore it.\r
+                 * XXX - potential security hazard could\r
+                 *   be detected here.\r
+                 */\r
+                DprintQ((_res.options & RES_DEBUG) ||\r
+                    (_res.pfcode & RES_PRF_REPLY),\r
+                    (stdout, ";; wrong query name:\n"),\r
+                    ans, (resplen>anssiz)?anssiz:resplen);\r
+                goto wait;\r
+            }\r
+            if (anhp->rcode == SERVFAIL ||\r
+                anhp->rcode == NOTIMP ||\r
+                anhp->rcode == REFUSED) {\r
+                DprintQ(_res.options & RES_DEBUG,\r
+                    (stdout, "server rejected query:\n"),\r
+                    ans, (resplen>anssiz)?anssiz:resplen);\r
+                badns |= (1 << ns);\r
+                res_close();\r
+                /* don't retry if called from dig */\r
+                if (!_res.pfcode)\r
+                    goto next_ns;\r
+            }\r
+            if (!(_res.options & RES_IGNTC) && anhp->tc) {\r
+                /*\r
+                 * get rest of answer;\r
+                 * use TCP with same server.\r
+                 */\r
+                Dprint(_res.options & RES_DEBUG,\r
+                       (stdout, ";; truncated answer\n"));\r
+                v_circuit = 1;\r
+                res_close();\r
+                goto same_ns;\r
+            }\r
+        } /*if vc/dg*/\r
+        Dprint((_res.options & RES_DEBUG) ||\r
+               ((_res.pfcode & RES_PRF_REPLY) &&\r
+            (_res.pfcode & RES_PRF_HEAD1)),\r
+               (stdout, ";; got answer:\n"));\r
+        DprintQ((_res.options & RES_DEBUG) ||\r
+            (_res.pfcode & RES_PRF_REPLY),\r
+            (stdout, ""),\r
+            ans, (resplen>anssiz)?anssiz:resplen);\r
+        /*\r
+         * If using virtual circuits, we assume that the first server\r
+         * is preferred over the rest (i.e. it is on the local\r
+         * machine) and only keep that one open.\r
+         * If we have temporarily opened a virtual circuit,\r
+         * or if we haven't been asked to keep a socket open,\r
+         * close the socket.\r
+         */\r
+        if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||\r
+            !(_res.options & RES_STAYOPEN)) {\r
+            res_close();\r
+        }\r
+        if (Rhook) {\r
+            int done = 0, loops = 0;\r
+\r
+            do {\r
+                res_sendhookact act;\r
+\r
+                act = (*Rhook)(nsap, buf, buflen,\r
+                           ans, anssiz, &resplen);\r
+                switch (act) {\r
+                case res_goahead:\r
+                case res_done:\r
+                    done = 1;\r
+                    break;\r
+                case res_nextns:\r
+                    res_close();\r
+                    goto next_ns;\r
+                case res_modified:\r
+                    /* give the hook another try */\r
+                    if (++loops < 42) /*doug adams*/\r
+                        break;\r
+                    /*FALLTHROUGH*/\r
+                case res_error:\r
+                    /*FALLTHROUGH*/\r
+                default:\r
+                    return (-1);\r
+                }\r
+            } while (!done);\r
+\r
+        }\r
+        return (resplen);\r
+    next_ns: ;\r
+       } /*foreach ns*/\r
+    } /*foreach retry*/\r
+    res_close();\r
+    if (!v_circuit) {\r
+        if (!gotsomewhere)\r
+            errno = ECONNREFUSED;   /* no nameservers found */\r
+        else\r
+            errno = ETIMEDOUT;  /* no answer obtained */\r
+    } else\r
+        errno = terrno;\r
+    return (-1);\r
+}\r
+\r
+/*\r
+ * This routine is for closing the socket if a virtual circuit is used and\r
+ * the program wants to close it.  This provides support for endhostent()\r
+ * which expects to close the socket.\r
+ *\r
+ * This routine is not expected to be user visible.\r
+ */\r
+void\r
+res_close()\r
+{\r
+    if (s >= 0) {\r
+        (void) close(s);\r
+        s = -1;\r
+        connected = 0;\r
+        vc = 0;\r
+    }\r
+}\r
diff --git a/StdLib/BsdSocketLib/res_update.c b/StdLib/BsdSocketLib/res_update.c
new file mode 100644 (file)
index 0000000..1ad8a87
--- /dev/null
@@ -0,0 +1,556 @@
+#if !defined(lint) && !defined(SABER)\r
+static char rcsid[] = "$Id: res_update.c,v 1.1.1.1 2003/11/19 01:51:39 kyu3 Exp $";\r
+#endif /* not lint */\r
+\r
+/*\r
+ * Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by Intel Corporation and\r
+ *    its contributors.\r
+ *\r
+ * 4. Neither the name of Intel Corporation or its contributors may be\r
+ *    used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+ * THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*\r
+ * Based on the Dynamic DNS reference implementation by Viraj Bais\r
+ * <viraj_bais@ccm.fm.intel.com>\r
+ */\r
+\r
+#include <sys/param.h>\r
+#include <sys/socket.h>\r
+#include <sys/time.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <arpa/nameser.h>\r
+#include <errno.h>\r
+#include <limits.h>\r
+#include <netdb.h>\r
+#include <resolv.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+/*\r
+ * Separate a linked list of records into groups so that all records\r
+ * in a group will belong to a single zone on the nameserver.\r
+ * Create a dynamic update packet for each zone and send it to the\r
+ * nameservers for that zone, and await answer.\r
+ * Abort if error occurs in updating any zone.\r
+ * Return the number of zones updated on success, < 0 on error.\r
+ *\r
+ * On error, caller must deal with the unsynchronized zones\r
+ * eg. an A record might have been successfully added to the forward\r
+ * zone but the corresponding PTR record would be missing if error\r
+ * was encountered while updating the reverse zone.\r
+ */\r
+\r
+#define NSMAX 16\r
+\r
+struct ns1 {\r
+    char nsname[MAXDNAME];\r
+    struct in_addr nsaddr1;\r
+};\r
+\r
+struct zonegrp {\r
+    char        z_origin[MAXDNAME];\r
+    int16_t     z_class;\r
+    char        z_soardata[MAXDNAME + 5 * INT32SZ];\r
+    struct ns1  z_ns[NSMAX];\r
+    int     z_nscount;\r
+    ns_updrec * z_rr;\r
+    struct zonegrp *z_next;\r
+};\r
+\r
+\r
+int\r
+res_update(ns_updrec *rrecp_in) {\r
+    ns_updrec *rrecp, *tmprrecp;\r
+    u_char buf[PACKETSZ], answer[PACKETSZ], packet[2*PACKETSZ];\r
+    char name[MAXDNAME], zname[MAXDNAME], primary[MAXDNAME],\r
+         mailaddr[MAXDNAME];\r
+    u_char soardata[2*MAXCDNAME+5*INT32SZ];\r
+    char *dname, *svdname, *cp1, *target;\r
+    u_char *cp, *eom;\r
+    HEADER *hp = (HEADER *) answer;\r
+    struct zonegrp *zptr = NULL, *tmpzptr, *prevzptr, *zgrp_start = NULL;\r
+    int i, j, k = 0, n, ancount, nscount, arcount, rcode, rdatasize,\r
+        newgroup, done, myzone, seen_before, numzones = 0;\r
+    u_int16_t dlen, class, qclass, type, qtype;\r
+    u_int32_t ttl;\r
+\r
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {\r
+        h_errno = NETDB_INTERNAL;\r
+        return (-1);\r
+    }\r
+\r
+    for (rrecp = rrecp_in; rrecp; rrecp = rrecp->r_next) {\r
+        dname = rrecp->r_dname;\r
+        n = (int)strlen(dname);\r
+        if (dname[n-1] == '.')\r
+            dname[n-1] = '\0';\r
+        qtype = T_SOA;\r
+        qclass = rrecp->r_class;\r
+        done = 0;\r
+        seen_before = 0;\r
+\r
+        while (!done && dname) {\r
+            if (qtype == T_SOA) {\r
+            for (tmpzptr = zgrp_start;\r
+                 tmpzptr && !seen_before;\r
+                 tmpzptr = tmpzptr->z_next) {\r
+                if (strcasecmp(dname,\r
+                           tmpzptr->z_origin) == 0 &&\r
+                    tmpzptr->z_class == qclass)\r
+                    seen_before++;\r
+                for (tmprrecp = tmpzptr->z_rr;\r
+                     tmprrecp && !seen_before;\r
+                     tmprrecp = tmprrecp->r_grpnext)\r
+                if (strcasecmp(dname, tmprrecp->r_dname) == 0\r
+                    && tmprrecp->r_class == qclass) {\r
+                    seen_before++;\r
+                    break;\r
+                }\r
+                if (seen_before) {\r
+                    /*\r
+                     * Append to the end of\r
+                     * current group.\r
+                     */\r
+                    for (tmprrecp = tmpzptr->z_rr;\r
+                         tmprrecp->r_grpnext;\r
+                         tmprrecp = tmprrecp->r_grpnext)\r
+                        (void)NULL;\r
+                    tmprrecp->r_grpnext = rrecp;\r
+                    rrecp->r_grpnext = NULL;\r
+                    done = 1;\r
+                    break;\r
+                }\r
+            }\r
+        } else if (qtype == T_A) {\r
+            for (tmpzptr = zgrp_start;\r
+             tmpzptr && !done;\r
+             tmpzptr = tmpzptr->z_next)\r
+                for (i = 0; i < tmpzptr->z_nscount; i++)\r
+                if (tmpzptr->z_class == qclass &&\r
+                    strcasecmp(tmpzptr->z_ns[i].nsname,\r
+                           dname) == 0 &&\r
+                    tmpzptr->z_ns[i].nsaddr1.s_addr != 0) {\r
+                    zptr->z_ns[k].nsaddr1.s_addr =\r
+                     tmpzptr->z_ns[i].nsaddr1.s_addr;\r
+                    done = 1;\r
+                    break;\r
+                }\r
+        }\r
+        if (done)\r
+            break;\r
+        n = res_mkquery(QUERY, dname, qclass, qtype, NULL,\r
+                0, NULL, buf, sizeof buf);\r
+        if (n <= 0) {\r
+            fprintf(stderr, "res_update: mkquery failed\n");\r
+            return (n);\r
+        }\r
+        n = res_send(buf, n, answer, sizeof answer);\r
+        if (n < 0) {\r
+            fprintf(stderr, "res_update: send error for %s\n",\r
+                rrecp->r_dname);\r
+            return (n);\r
+        }\r
+        if (n < HFIXEDSZ)\r
+            return (-1);\r
+        ancount = ntohs(hp->ancount);\r
+        nscount = ntohs(hp->nscount);\r
+        arcount = ntohs(hp->arcount);\r
+        rcode = hp->rcode;\r
+        cp = answer + HFIXEDSZ;\r
+        eom = answer + n;\r
+        /* skip the question section */\r
+        n = dn_skipname(cp, eom);\r
+        if (n < 0 || cp + n + 2 * INT16SZ > eom)\r
+            return (-1);\r
+        cp += n + 2 * INT16SZ;\r
+\r
+        if (qtype == T_SOA) {\r
+            if (ancount == 0 && nscount == 0 && arcount == 0) {\r
+            /*\r
+             * if (rcode == NOERROR) then the dname exists but\r
+             * has no soa record associated with it.\r
+             * if (rcode == NXDOMAIN) then the dname does not\r
+             * exist and the server is replying out of NCACHE.\r
+             * in either case, proceed with the next try\r
+             */\r
+            dname = strchr(dname, '.');\r
+            if (dname != NULL)\r
+                dname++;\r
+            continue;\r
+            } else if ((rcode == NOERROR || rcode == NXDOMAIN) &&\r
+                   ancount == 0 &&\r
+                   nscount == 1 && arcount == 0) {\r
+            /*\r
+             * name/data does not exist, soa record supplied in the\r
+             * authority section\r
+             */\r
+            /* authority section must contain the soa record */\r
+            if ((n = dn_expand(answer, eom, cp, zname,\r
+                    sizeof zname)) < 0)\r
+                return (n);\r
+            cp += n;\r
+            if (cp + 2 * INT16SZ > eom)\r
+                return (-1);\r
+            GETSHORT(type, cp);\r
+            GETSHORT(class, cp);\r
+            if (type != T_SOA || class != qclass) {\r
+                fprintf(stderr, "unknown answer\n");\r
+                return (-1);\r
+            }\r
+            myzone = 0;\r
+            svdname = dname;\r
+            while (dname)\r
+                if (strcasecmp(dname, zname) == 0) {\r
+                myzone = 1;\r
+                break;\r
+                } else if ((dname = strchr(dname, '.')) != NULL)\r
+                dname++;\r
+            if (!myzone) {\r
+                dname = strchr(svdname, '.');\r
+                if (dname != NULL)\r
+                dname++;\r
+                continue;\r
+            }\r
+            nscount = 0;\r
+            /* fallthrough */\r
+            } else if (rcode == NOERROR && ancount == 1) {\r
+            /*\r
+             * found the zone name\r
+             * new servers will supply NS records for the zone\r
+             * in authority section and A records for those\r
+             * nameservers in the additional section\r
+             * older servers have to be explicitly queried for\r
+             * NS records for the zone\r
+             */\r
+            /* answer section must contain the soa record */\r
+            if ((n = dn_expand(answer, eom, cp, zname,\r
+                           sizeof zname)) < 0)\r
+                return (n);\r
+            else\r
+                cp += n;\r
+            if (cp + 2 * INT16SZ > eom)\r
+                return (-1);\r
+            GETSHORT(type, cp);\r
+            GETSHORT(class, cp);\r
+            if (type == T_CNAME) {\r
+                dname = strchr(dname, '.');\r
+                if (dname != NULL)\r
+                    dname++;\r
+                continue;\r
+            }\r
+            if (strcasecmp(dname, zname) != 0 ||\r
+                type != T_SOA ||\r
+                class != rrecp->r_class) {\r
+                fprintf(stderr, "unknown answer\n");\r
+                return (-1);\r
+            }\r
+            /* FALLTHROUGH */\r
+            } else {\r
+            fprintf(stderr,\r
+        "unknown response: ans=%d, auth=%d, add=%d, rcode=%d\n",\r
+                ancount, nscount, arcount, hp->rcode);\r
+            return (-1);\r
+            }\r
+            if (cp + INT32SZ + INT16SZ > eom)\r
+                return (-1);\r
+            /* continue processing the soa record */\r
+            GETLONG(ttl, cp);\r
+            GETSHORT(dlen, cp);\r
+            if (cp + dlen > eom)\r
+                return (-1);\r
+            newgroup = 1;\r
+            zptr = zgrp_start;\r
+            prevzptr = NULL;\r
+            while (zptr) {\r
+            if (strcasecmp(zname, zptr->z_origin) == 0 &&\r
+                type == T_SOA && class == qclass) {\r
+                newgroup = 0;\r
+                break;\r
+            }\r
+            prevzptr = zptr;\r
+            zptr = zptr->z_next;\r
+            }\r
+            if (!newgroup) {\r
+            for (tmprrecp = zptr->z_rr;\r
+                 tmprrecp->r_grpnext;\r
+                 tmprrecp = tmprrecp->r_grpnext)\r
+                    ;\r
+            tmprrecp->r_grpnext = rrecp;\r
+            rrecp->r_grpnext = NULL;\r
+            done = 1;\r
+            cp += dlen;\r
+            break;\r
+            } else {\r
+            if ((n = dn_expand(answer, eom, cp, primary,\r
+                           sizeof primary)) < 0)\r
+                return (n);\r
+            cp += n;\r
+            /*\r
+             * We don't have to bounds check here because the\r
+             * next use of 'cp' is in dn_expand().\r
+             */\r
+            cp1 = (char *)soardata;\r
+            strcpy(cp1, primary);\r
+            cp1 += strlen(cp1) + 1;\r
+            if ((n = dn_expand(answer, eom, cp, mailaddr,\r
+                           sizeof mailaddr)) < 0)\r
+                return (n);\r
+            cp += n;\r
+            strcpy(cp1, mailaddr);\r
+            cp1 += strlen(cp1) + 1;\r
+            if (cp + 5*INT32SZ > eom)\r
+                return (-1);\r
+            memcpy(cp1, cp, 5*INT32SZ);\r
+            cp += 5*INT32SZ;\r
+            cp1 += 5*INT32SZ;\r
+            rdatasize = (int)((u_char *)cp1 - soardata);\r
+            zptr = calloc(1, sizeof(struct zonegrp));\r
+            if (zptr == NULL)\r
+                        return (-1);\r
+            if (zgrp_start == NULL)\r
+                zgrp_start = zptr;\r
+            else\r
+                prevzptr->z_next = zptr;\r
+            zptr->z_rr = rrecp;\r
+            rrecp->r_grpnext = NULL;\r
+            strcpy(zptr->z_origin, zname);\r
+            zptr->z_class = class;\r
+            memcpy(zptr->z_soardata, soardata, rdatasize);\r
+            /* fallthrough to process NS and A records */\r
+            }\r
+        } else if (qtype == T_NS) {\r
+            if (rcode == NOERROR && ancount > 0) {\r
+            strcpy(zname, dname);\r
+            for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {\r
+                if (strcasecmp(zname, zptr->z_origin) == 0)\r
+                break;\r
+            }\r
+            if (zptr == NULL)\r
+                /* should not happen */\r
+                return (-1);\r
+            if (nscount > 0) {\r
+                /*\r
+                 * answer and authority sections contain\r
+                 * the same information, skip answer section\r
+                 */\r
+                for (j = 0; j < ancount; j++) {\r
+                n = dn_skipname(cp, eom);\r
+                if (n < 0)\r
+                    return (-1);\r
+                n += 2*INT16SZ + INT32SZ;\r
+                if (cp + n + INT16SZ > eom)\r
+                    return (-1);\r
+                cp += n;\r
+                GETSHORT(dlen, cp);\r
+                cp += dlen;\r
+                }\r
+            } else\r
+                nscount = ancount;\r
+            /* fallthrough to process NS and A records */\r
+            } else {\r
+            fprintf(stderr, "cannot determine nameservers for %s:\\r
+ans=%d, auth=%d, add=%d, rcode=%d\n",\r
+                dname, ancount, nscount, arcount, hp->rcode);\r
+            return (-1);\r
+            }\r
+        } else if (qtype == T_A) {\r
+            if (rcode == NOERROR && ancount > 0) {\r
+            arcount = ancount;\r
+            ancount = nscount = 0;\r
+            /* fallthrough to process A records */\r
+            } else {\r
+            fprintf(stderr, "cannot determine address for %s:\\r
+ans=%d, auth=%d, add=%d, rcode=%d\n",\r
+                dname, ancount, nscount, arcount, hp->rcode);\r
+            return (-1);\r
+            }\r
+        }\r
+        /* process NS records for the zone */\r
+        j = 0;\r
+        for (i = 0; i < nscount; i++) {\r
+            if ((n = dn_expand(answer, eom, cp, name,\r
+                    sizeof name)) < 0)\r
+            return (n);\r
+            cp += n;\r
+            if (cp + 3 * INT16SZ + INT32SZ > eom)\r
+                return (-1);\r
+            GETSHORT(type, cp);\r
+            GETSHORT(class, cp);\r
+            GETLONG(ttl, cp);\r
+            GETSHORT(dlen, cp);\r
+            if (cp + dlen > eom)\r
+            return (-1);\r
+            if (strcasecmp(name, zname) == 0 &&\r
+            type == T_NS && class == qclass) {\r
+                if ((n = dn_expand(answer, eom, cp,\r
+                           name, sizeof name)) < 0)\r
+                    return (n);\r
+                target = zptr->z_ns[j++].nsname;\r
+                strcpy(target, name);\r
+            }\r
+            cp += dlen;\r
+        }\r
+        if (zptr->z_nscount == 0)\r
+            zptr->z_nscount = j;\r
+        /* get addresses for the nameservers */\r
+        for (i = 0; i < arcount; i++) {\r
+            if ((n = dn_expand(answer, eom, cp, name,\r
+                    sizeof name)) < 0)\r
+            return (n);\r
+            cp += n;\r
+            if (cp + 3 * INT16SZ + INT32SZ > eom)\r
+            return (-1);\r
+            GETSHORT(type, cp);\r
+            GETSHORT(class, cp);\r
+            GETLONG(ttl, cp);\r
+            GETSHORT(dlen, cp);\r
+            if (cp + dlen > eom)\r
+                return (-1);\r
+            if (type == T_A && dlen == INT32SZ && class == qclass) {\r
+            for (j = 0; j < zptr->z_nscount; j++)\r
+                if (strcasecmp(name, zptr->z_ns[j].nsname) == 0) {\r
+                memcpy(&zptr->z_ns[j].nsaddr1.s_addr, cp,\r
+                       INT32SZ);\r
+                break;\r
+                }\r
+            }\r
+            cp += dlen;\r
+        }\r
+        if (zptr->z_nscount == 0) {\r
+            dname = zname;\r
+            qtype = T_NS;\r
+            continue;\r
+        }\r
+        done = 1;\r
+        for (k = 0; k < zptr->z_nscount; k++)\r
+            if (zptr->z_ns[k].nsaddr1.s_addr == 0) {\r
+            done = 0;\r
+            dname = zptr->z_ns[k].nsname;\r
+            qtype = T_A;\r
+            }\r
+\r
+        } /* while */\r
+    }\r
+\r
+    _res.options |= RES_DEBUG;\r
+    for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {\r
+\r
+        /* append zone section */\r
+        rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,\r
+                     zptr->z_class, ns_t_soa, 0);\r
+        if (rrecp == NULL) {\r
+            fprintf(stderr, "saverrec error\n");\r
+            fflush(stderr);\r
+            return (-1);\r
+        }\r
+        rrecp->r_grpnext = zptr->z_rr;\r
+        zptr->z_rr = rrecp;\r
+\r
+        n = res_mkupdate(zptr->z_rr, packet, sizeof packet);\r
+        if (n < 0) {\r
+            fprintf(stderr, "res_mkupdate error\n");\r
+            fflush(stderr);\r
+            return (-1);\r
+        } else\r
+            fprintf(stdout, "res_mkupdate: packet size = %d\n", n);\r
+\r
+        /*\r
+         * Override the list of NS records from res_init() with\r
+         * the authoritative nameservers for the zone being updated.\r
+         * Sort primary to be the first in the list of nameservers.\r
+         */\r
+        for (i = 0; i < zptr->z_nscount; i++) {\r
+            if (strcasecmp(zptr->z_ns[i].nsname,\r
+                       zptr->z_soardata) == 0) {\r
+                struct in_addr tmpaddr;\r
+\r
+                if (i != 0) {\r
+                    strcpy(zptr->z_ns[i].nsname,\r
+                           zptr->z_ns[0].nsname);\r
+                    strcpy(zptr->z_ns[0].nsname,\r
+                           zptr->z_soardata);\r
+                    tmpaddr = zptr->z_ns[i].nsaddr1;\r
+                    zptr->z_ns[i].nsaddr1 =\r
+                        zptr->z_ns[0].nsaddr1;\r
+                    zptr->z_ns[0].nsaddr1 = tmpaddr;\r
+                }\r
+                break;\r
+            }\r
+        }\r
+        for (i = 0; i < MAXNS; i++) {\r
+            _res.nsaddr_list[i].sin_addr = zptr->z_ns[i].nsaddr1;\r
+            _res.nsaddr_list[i].sin_family = AF_INET;\r
+            _res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);\r
+        }\r
+        _res.nscount = (zptr->z_nscount < MAXNS) ?\r
+                    zptr->z_nscount : MAXNS;\r
+        n = res_send(packet, n, answer, sizeof(answer));\r
+        if (n < 0) {\r
+            fprintf(stderr, "res_send: send error, n=%d\n", n);\r
+            break;\r
+        } else\r
+            numzones++;\r
+    }\r
+\r
+    /* free malloc'ed memory */\r
+    while(zgrp_start) {\r
+        zptr = zgrp_start;\r
+        zgrp_start = zgrp_start->z_next;\r
+        res_freeupdrec(zptr->z_rr);  /* Zone section we allocated. */\r
+        free((char *)zptr);\r
+    }\r
+\r
+    return (numzones);\r
+}\r
diff --git a/StdLib/BsdSocketLib/send.c b/StdLib/BsdSocketLib/send.c
new file mode 100644 (file)
index 0000000..e0ec643
--- /dev/null
@@ -0,0 +1,97 @@
+/** @file\r
+  Implement the send API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Send data using a network connection.\r
+\r
+  The ::send routine queues data to the network for transmission.\r
+  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] buffer    Address of a buffer containing the data to send.\r
+    \r
+  @param [in] length    Length of the buffer in bytes.\r
+\r
+  @param [in] flags     Message control flags\r
+\r
+  @returns    ::send returns the number of data bytes that were\r
+              sent and -1 when an error occurs.  In the case of\r
+              an error, errno contains more details.\r
+\r
+ **/\r
+ssize_t\r
+send (\r
+  int s,\r
+  CONST void * buffer,\r
+  size_t length,\r
+  int flags\r
+  )\r
+{\r
+  ssize_t LengthInBytes;\r
+  CONST UINT8 * pData;\r
+  struct __filedes * pDescriptor;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  LengthInBytes = -1;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s,\r
+                                            &pDescriptor,\r
+                                            &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Send the data using the socket\r
+    //\r
+    pData = buffer;\r
+    do {\r
+      errno = 0;\r
+      Status = pSocketProtocol->pfnSend ( pSocketProtocol,\r
+                                          flags,\r
+                                          length,\r
+                                          pData,\r
+                                          (size_t *)&LengthInBytes,\r
+                                          NULL,\r
+                                          0,\r
+                                          &errno );\r
+      if ( EFI_ERROR ( Status )) {\r
+        LengthInBytes = -1;\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Account for the data sent\r
+      //\r
+      pData += LengthInBytes;\r
+      length -= LengthInBytes;\r
+      // TODO: Add non-blocking check\r
+    } while (( 0 != length ) && ( EFI_NOT_READY == Status ));\r
+  }\r
+\r
+  //\r
+  //  Return the number of data bytes sent, -1 for errors\r
+  //\r
+  return (INT32)LengthInBytes;\r
+}\r
diff --git a/StdLib/BsdSocketLib/sendto.c b/StdLib/BsdSocketLib/sendto.c
new file mode 100644 (file)
index 0000000..338eb36
--- /dev/null
@@ -0,0 +1,103 @@
+/** @file\r
+  Implement the sendto API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Send data using a network connection.\r
+\r
+  The ::send routine queues data to the network for transmission.\r
+  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] buffer    Address of a buffer containing the data to send.\r
+    \r
+  @param [in] length    Length of the buffer in bytes.\r
+\r
+  @param [in] flags     Message control flags\r
+\r
+  @param [in] to        Remote system address\r
+\r
+  @param [in] tolen     Length of remote system address structure\r
+\r
+  @returns    ::send returns the number of data bytes that were\r
+              sent and -1 when an error occurs.  In the case of\r
+              an error, errno contains more details.\r
+\r
+ **/\r
+ssize_t\r
+sendto (\r
+  int s,\r
+  const void * buffer,\r
+  size_t length,\r
+  int flags,\r
+  const struct sockaddr * to,\r
+  socklen_t tolen\r
+  )\r
+{\r
+  ssize_t LengthInBytes;\r
+  CONST UINT8 * pData;\r
+  struct __filedes * pDescriptor;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  LengthInBytes = -1;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s,\r
+                                            &pDescriptor,\r
+                                            &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Send the data using the socket\r
+    //\r
+    pData = buffer;\r
+    do {\r
+      errno = 0;\r
+      Status = pSocketProtocol->pfnSend ( pSocketProtocol,\r
+                                          flags,\r
+                                          length,\r
+                                          pData,\r
+                                          (size_t *)&LengthInBytes,\r
+                                          to,\r
+                                          tolen,\r
+                                          &errno );\r
+      if ( EFI_ERROR ( Status )) {\r
+        LengthInBytes = -1;\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Account for the data sent\r
+      //\r
+      pData += LengthInBytes;\r
+      length -= LengthInBytes;\r
+      // TODO: Add non-blocking check\r
+    } while (( 0 != length ) && ( EFI_NOT_READY == Status ));\r
+  }\r
+\r
+  //\r
+  //  Return the number of data bytes sent, -1 for errors\r
+  //\r
+  return (INT32)LengthInBytes;\r
+}\r
diff --git a/StdLib/BsdSocketLib/sethostname.c b/StdLib/BsdSocketLib/sethostname.c
new file mode 100644 (file)
index 0000000..7863e8c
--- /dev/null
@@ -0,0 +1,117 @@
+/*\r
+ * Copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software must\r
+ *    display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by Intel Corporation and its\r
+ *    contributors.\r
+ *\r
+ * 4. Neither the name of Intel Corporation or its contributors may be used to\r
+ *    endorse or promote products derived from this software without specific\r
+ *    prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR\r
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+#include <errno.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+#include <wchar.h>\r
+\r
+/*++\r
+\r
+Module Name:\r
+\r
+    sethostname.c\r
+\r
+Abstract:\r
+\r
+    Map FreeBSD sethostname call to EFI Interface\r
+\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+int\r
+sethostname(\r
+  const char * name,\r
+  size_t namelen\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Set the hostname for this system.\r
+\r
+Arguments:\r
+\r
+  name    - Pointer to hostname.\r
+  namelen   - Length of name\r
+\r
+Returns:\r
+\r
+  0 on success, -1 if not set\r
+\r
+--*/\r
+{\r
+  int SetStatus;\r
+  char * pName;\r
+\r
+  //\r
+  //  Allocate a new buffer for name since the input value\r
+  //  does not need to be zero terminated\r
+  //\r
+  pName = malloc ( namelen + 1 );\r
+  if ( NULL == pName ) {\r
+    errno = ENOMEM;\r
+    SetStatus = -1;\r
+  }\r
+  else {\r
+    //\r
+    //  Create a zero terminated string for name\r
+    //\r
+    memcpy ( pName, name, namelen );\r
+    pName [ namelen ] = 0;\r
+  \r
+    //\r
+    //  Set the environment variable\r
+    //\r
+    SetStatus = setenv ("HOSTNAME", pName, TRUE);\r
+\r
+    //\r
+    //  Free the temporary buffer\r
+    //\r
+    free ( pName );\r
+  }\r
+\r
+  //\r
+  //  Return the results\r
+  //\r
+  return SetStatus;\r
+}\r
diff --git a/StdLib/BsdSocketLib/setsockopt.c b/StdLib/BsdSocketLib/setsockopt.c
new file mode 100644 (file)
index 0000000..74c948c
--- /dev/null
@@ -0,0 +1,65 @@
+/** @file\r
+  Implement the setsockopt API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Set the socket options\r
+\r
+  @param [in] s               Socket file descriptor returned from ::socket.\r
+  @param [in] level           Option protocol level\r
+  @param [in] option_name     Name of the option\r
+  @param [in] option_value    Buffer containing the option value\r
+  @param [in] option_len      Length of the value in bytes\r
+\r
+  @retval   Zero (0) upon success\r
+  @retval   Minus one (-1) upon failure, errno set with additional error information\r
+\r
+**/\r
+int\r
+setsockopt (\r
+  IN int s,\r
+  IN int level,\r
+  IN int option_name,\r
+  IN CONST void * option_value,\r
+  IN socklen_t option_len\r
+  )\r
+{\r
+  int OptionStatus;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+  \r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Set the socket option\r
+    //\r
+    Status = pSocketProtocol->pfnOptionSet ( pSocketProtocol,\r
+                                             level,\r
+                                             option_name,\r
+                                             option_value,\r
+                                             option_len,\r
+                                             &errno );\r
+  }\r
+  \r
+  //\r
+  //  Return the operation stauts\r
+  //\r
+  OptionStatus = ( 0 == errno ) ? 0 : -1;\r
+  return OptionStatus;\r
+}\r
diff --git a/StdLib/BsdSocketLib/shutdown.c b/StdLib/BsdSocketLib/shutdown.c
new file mode 100644 (file)
index 0000000..4c00fea
--- /dev/null
@@ -0,0 +1,72 @@
+/** @file\r
+  Implement the shutdown API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Shutdown the socket receive and transmit operations\r
+\r
+  The ::shutdown routine stops socket receive and transmit operations.\r
+  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] how       Which operations to shutdown\r
+  \r
+  @returns    ::shutdown returns the zero (0) if successful or -1 when an\r
+              error occurs.  In the latter case, errno contains more details.\r
+\r
+ **/\r
+int\r
+shutdown (\r
+  int s,\r
+  int how\r
+  )\r
+{\r
+  int RetVal;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  RetVal = -1;\r
+\r
+  //\r
+  //  Locate the context for this socket\r
+  //\r
+  pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno );\r
+  if ( NULL != pSocketProtocol ) {\r
+    //\r
+    //  Receive the data from the socket\r
+    //\r
+    Status = pSocketProtocol->pfnShutdown ( pSocketProtocol,\r
+                                            how,\r
+                                            &errno );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Success\r
+      //\r
+      RetVal = 0;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return RetVal;\r
+}\r
diff --git a/StdLib/BsdSocketLib/socket.c b/StdLib/BsdSocketLib/socket.c
new file mode 100644 (file)
index 0000000..3754a29
--- /dev/null
@@ -0,0 +1,286 @@
+/** @file\r
+  Implement the socket API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+const struct fileops SocketOperations = {\r
+  BslSocketClose,     //  close\r
+  BslSocketRead,      //  read\r
+  BslSocketWrite,     //  write\r
+\r
+  //\r
+  //  Not supported\r
+  //\r
+  fnullop_fcntl,      //  fcntl\r
+  BslSocketPoll,      //  poll\r
+  fnullop_flush,      //  flush\r
+\r
+  fbadop_stat,        //  stat\r
+  fbadop_ioctl,       //  ioctl\r
+  fbadop_delete,      //  delete\r
+  fbadop_rmdir,       //  rmdir\r
+  fbadop_mkdir,       //  mkdir\r
+  fbadop_rename,      //  rename\r
+\r
+  NULL                //  lseek\r
+};\r
+\r
+\r
+/**\r
+  Translate from the socket file descriptor to the socket protocol.\r
+\r
+  @param [in] s             Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] ppDescriptor  Address to receive the descriptor structure\r
+                            address for the file\r
+  @param [in] pErrno        Address of the errno variable\r
+\r
+  @returns  A pointer to the socket protocol structure or NULL if\r
+            an invalid file descriptor was passed in.\r
+\r
+ **/\r
+EFI_SOCKET_PROTOCOL *\r
+BslFdToSocketProtocol (\r
+  int s,\r
+  struct __filedes ** ppDescriptor,\r
+  int * pErrno\r
+  )\r
+{\r
+  struct __filedes * pDescriptor;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  pSocketProtocol = NULL;\r
+\r
+  //\r
+  //  Validate the file descriptor\r
+  //\r
+  if ( !ValidateFD ( s, TRUE )) {\r
+    //\r
+    //  Bad file descriptor\r
+    //\r
+    *pErrno = EBADF;\r
+  }\r
+  else {\r
+    //\r
+    //  Get the descriptor for the file\r
+    //\r
+    pDescriptor = &gMD->fdarray [ s ];\r
+\r
+    //\r
+    //  Validate that the descriptor is associated with sockets\r
+    //\r
+    pSocketProtocol = BslValidateSocketFd ( pDescriptor, pErrno );\r
+    if (( NULL != ppDescriptor ) && ( NULL != pSocketProtocol )) {\r
+      *ppDescriptor = pDescriptor;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the socket protocol\r
+  //\r
+  return pSocketProtocol;\r
+}\r
+\r
+\r
+/**\r
+  Build a file descriptor for a socket.\r
+\r
+  @param [in] pSocketProtocol   Socket protocol structure address\r
+  \r
+  @param [in] pErrno            Address of the errno variable\r
+\r
+  @returns The file descriptor for the socket or -1 if an error occurs.\r
+\r
+ **/\r
+int\r
+BslSocketProtocolToFd (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  int FileDescriptor;\r
+  struct __filedes * pDescriptor;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  FileDescriptor = -1;\r
+\r
+  //\r
+  //  Locate a file descriptor\r
+  //\r
+  FileDescriptor = FindFreeFD ( VALID_CLOSED );\r
+  if( FileDescriptor < 0 ) {\r
+    //\r
+    // All available FDs are in use\r
+    //\r
+    errno = EMFILE;\r
+  }\r
+  else {\r
+    //\r
+    //  Initialize the file descriptor\r
+    //\r
+    pDescriptor = &gMD->fdarray [ FileDescriptor ];\r
+    pDescriptor->f_offset = 0;\r
+    pDescriptor->f_flag = 0;\r
+    pDescriptor->f_iflags = DTYPE_SOCKET;\r
+    pDescriptor->MyFD = (UINT16)FileDescriptor;\r
+    pDescriptor->Oflags = 0;\r
+    pDescriptor->Omode = S_ACC_READ | S_ACC_WRITE;\r
+    pDescriptor->RefCount = 1;\r
+    FILE_SET_MATURE ( pDescriptor );\r
+\r
+    //\r
+    //  Socket specific file descriptor initialization\r
+    //\r
+    pDescriptor->devdata = pSocketProtocol;\r
+    pDescriptor->f_ops = &SocketOperations;\r
+  }\r
+\r
+  //\r
+  //  Return the socket's file descriptor\r
+  //\r
+  return FileDescriptor;\r
+}\r
+\r
+\r
+/**\r
+  Creates an endpoint for network communication.\r
+\r
+  The ::Socket routine initializes the communication endpoint by providing\r
+  the support for the socket library function ::socket.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html">POSIX</a>\r
+  documentation for the socket routine is available online for reference.\r
+\r
+  @param [in] domain    Select the family of protocols for the client or server\r
+                        application.\r
+\r
+  @param [in] type      Specifies how to make the network connection.  The following values\r
+                        are supported:\r
+                        <ul>\r
+                          <li>\r
+                            SOCK_STREAM - Connect to TCP, provides a byte stream\r
+                            that is manipluated by read, recv, send and write.\r
+                          </li>\r
+                          <li>\r
+                            SOCK_SEQPACKET - Connect to TCP, provides sequenced packet stream\r
+                            that is manipulated by read, recv, send and write.\r
+                          </li>\r
+                          <li>\r
+                            SOCK_DGRAM - Connect to UDP, provides a datagram service that is\r
+                            manipulated by recvfrom and sendto.\r
+                          </li>\r
+                        </ul>\r
+\r
+  @param [in] protocol  Specifies the lower layer protocol to use.  The following\r
+                        values are supported:\r
+                        <ul>\r
+                          <li>IPPROTO_TCP</li> - This value must be combined with SOCK_STREAM.</li>\r
+                          <li>IPPROTO_UDP</li> - This value must be combined with SOCK_DGRAM.</li>\r
+                        </ul>\r
+\r
+  @returns This routine returns a file descriptor for the socket.\r
+\r
+ **/\r
+INT32\r
+socket (\r
+  IN INT32 domain,\r
+  IN INT32 type,\r
+  IN INT32 protocol\r
+  )\r
+{\r
+  INT32 FileDescriptor;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  FileDescriptor = -1;\r
+\r
+  //\r
+  //  Locate the socket protocol\r
+  //\r
+  errno = EslServiceGetProtocol ( &pSocketProtocol );\r
+  if ( 0 == errno ) {\r
+    //\r
+    //  Initialize the socket\r
+    //\r
+    Status = pSocketProtocol->pfnSocket ( pSocketProtocol,\r
+                                          domain,\r
+                                          type,\r
+                                          protocol,\r
+                                          &errno );\r
+    if ( !EFI_ERROR ( Status ))\r
+    {\r
+      //\r
+      //  Build the file descriptor for the socket\r
+      //\r
+      FileDescriptor = BslSocketProtocolToFd ( pSocketProtocol,\r
+                                               &errno );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the socket's file descriptor\r
+  //\r
+  return FileDescriptor;\r
+}\r
+\r
+\r
+/**\r
+  Validate the socket's file descriptor\r
+\r
+  @param [in] pDescriptor Descriptor for the file\r
+\r
+  @param [in] pErrno      Address of the errno variable\r
+\r
+  @returns  A pointer to the socket protocol structure or NULL if\r
+            an invalid file descriptor was passed in.\r
+\r
+ **/\r
+EFI_SOCKET_PROTOCOL *\r
+BslValidateSocketFd (\r
+  struct __filedes * pDescriptor,\r
+  int * pErrno\r
+  )\r
+{\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  *pErrno = ENOTSOCK;\r
+  pSocketProtocol = NULL;\r
+\r
+  //\r
+  //  Validate that the descriptor is associated with sockets\r
+  //\r
+  if ( DTYPE_SOCKET == ( pDescriptor->f_iflags & DTYPE_MASK )) {\r
+    //\r
+    //  Locate the socket protocol\r
+    //\r
+    pSocketProtocol = pDescriptor->devdata;\r
+    *pErrno = 0;\r
+  }\r
+\r
+  //\r
+  //  Return the socket protocol\r
+  //\r
+  return pSocketProtocol;\r
+}\r
diff --git a/StdLib/BsdSocketLib/write.c b/StdLib/BsdSocketLib/write.c
new file mode 100644 (file)
index 0000000..d04dda9
--- /dev/null
@@ -0,0 +1,51 @@
+/** @file\r
+  Implement the write API.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <SocketInternals.h>\r
+\r
+\r
+/**\r
+  Write support routine for sockets\r
+\r
+  @param [in] pDescriptor   Descriptor address for the file\r
+  @param [in] pOffset       File offset\r
+  @param [in] LengthInBytes Number of bytes to write\r
+  @param [in] pBuffer       Address of the data\r
+\r
+  @returns  The number of bytes written or -1 if an error occurs.\r
+\r
+**/\r
+ssize_t\r
+BslSocketWrite (\r
+  struct __filedes *pDescriptor,\r
+  off_t * pOffset,\r
+  size_t LengthInBytes,\r
+  const void * pBuffer\r
+  )\r
+{\r
+  ssize_t BytesWritten;\r
+\r
+  //\r
+  //  Send the data using the socket\r
+  //\r
+  BytesWritten = send ( pDescriptor->MyFD,\r
+                        pBuffer,\r
+                        LengthInBytes,\r
+                        0 );\r
+\r
+  //\r
+  //  Return the number of bytes written\r
+  //\r
+  return BytesWritten;\r
+}\r
diff --git a/StdLib/Efi/etc/host.conf b/StdLib/Efi/etc/host.conf
new file mode 100644 (file)
index 0000000..1d76541
--- /dev/null
@@ -0,0 +1,4 @@
+# Order to perform name searches
+dns, nis
+hosts
+
diff --git a/StdLib/Efi/etc/hosts b/StdLib/Efi/etc/hosts
new file mode 100644 (file)
index 0000000..60cd861
--- /dev/null
@@ -0,0 +1,9 @@
+# IPv4 hosts\r
+127.0.0.1       localhost\r
+\r
+# IPv6 hosts\r
+::1             localhost ip6-localhost ip6-loopback\r
+fe00::0         ip6-localnet\r
+ff00::0         ip6-mcastprefix\r
+ff02::1         ip6-allnodes\r
+ff02::2         ip6-allrouters\r
diff --git a/StdLib/Efi/etc/networks b/StdLib/Efi/etc/networks
new file mode 100644 (file)
index 0000000..b0101c4
--- /dev/null
@@ -0,0 +1,3 @@
+# symbolic names for networks, see networks(5) for more information
+link-local 169.254.0.0
+loopback   127.0.0.1
diff --git a/StdLib/Efi/etc/protocols b/StdLib/Efi/etc/protocols
new file mode 100644 (file)
index 0000000..10e277c
--- /dev/null
@@ -0,0 +1,59 @@
+# Internet (IP) protocols
+#
+# Updated from http://www.iana.org/assignments/protocol-numbers and other
+# sources.
+# New protocols will be added on request if they have been officially
+# assigned by IANA and are not historical.
+# If you need a huge list of used numbers please install the nmap package.
+
+ip     0       IP              # internet protocol, pseudo protocol number
+#hopopt        0       HOPOPT          # IPv6 Hop-by-Hop Option [RFC1883]
+icmp   1       ICMP            # internet control message protocol
+igmp   2       IGMP            # Internet Group Management
+ggp    3       GGP             # gateway-gateway protocol
+ipencap        4       IP-ENCAP        # IP encapsulated in IP (officially ``IP'')
+st     5       ST              # ST datagram mode
+tcp    6       TCP             # transmission control protocol
+egp    8       EGP             # exterior gateway protocol
+igp    9       IGP             # any private interior gateway (Cisco)
+pup    12      PUP             # PARC universal packet protocol
+udp    17      UDP             # user datagram protocol
+hmp    20      HMP             # host monitoring protocol
+xns-idp        22      XNS-IDP         # Xerox NS IDP
+rdp    27      RDP             # "reliable datagram" protocol
+iso-tp4        29      ISO-TP4         # ISO Transport Protocol class 4 [RFC905]
+xtp    36      XTP             # Xpress Transfer Protocol
+ddp    37      DDP             # Datagram Delivery Protocol
+idpr-cmtp 38   IDPR-CMTP       # IDPR Control Message Transport
+ipv6   41      IPv6            # Internet Protocol, version 6
+ipv6-route 43  IPv6-Route      # Routing Header for IPv6
+ipv6-frag 44   IPv6-Frag       # Fragment Header for IPv6
+idrp   45      IDRP            # Inter-Domain Routing Protocol
+rsvp   46      RSVP            # Reservation Protocol
+gre    47      GRE             # General Routing Encapsulation
+esp    50      IPSEC-ESP       # Encap Security Payload [RFC2406]
+ah     51      IPSEC-AH        # Authentication Header [RFC2402]
+skip   57      SKIP            # SKIP
+ipv6-icmp 58   IPv6-ICMP       # ICMP for IPv6
+ipv6-nonxt 59  IPv6-NoNxt      # No Next Header for IPv6
+ipv6-opts 60   IPv6-Opts       # Destination Options for IPv6
+rspf   73      RSPF CPHB       # Radio Shortest Path First (officially CPHB)
+vmtp   81      VMTP            # Versatile Message Transport
+eigrp  88      EIGRP           # Enhanced Interior Routing Protocol (Cisco)
+ospf   89      OSPFIGP         # Open Shortest Path First IGP
+ax.25  93      AX.25           # AX.25 frames
+ipip   94      IPIP            # IP-within-IP Encapsulation Protocol
+etherip        97      ETHERIP         # Ethernet-within-IP Encapsulation [RFC3378]
+encap  98      ENCAP           # Yet Another IP encapsulation [RFC1241]
+#      99                      # any private encryption scheme
+pim    103     PIM             # Protocol Independent Multicast
+ipcomp 108     IPCOMP          # IP Payload Compression Protocol
+vrrp   112     VRRP            # Virtual Router Redundancy Protocol
+l2tp   115     L2TP            # Layer Two Tunneling Protocol [RFC2661]
+isis   124     ISIS            # IS-IS over IPv4
+sctp   132     SCTP            # Stream Control Transmission Protocol
+fc     133     FC              # Fibre Channel
+udplite        136     UDPLite         # UDP-Lite
+mpls-in-ip 137 MPLS-in-IP      # MPLS-in-IP [RFC4023]
+manet  138                     # MANET Protocols
+hip    139     HIP             # Host Identity Protocol
diff --git a/StdLib/Efi/etc/resolv.conf b/StdLib/Efi/etc/resolv.conf
new file mode 100644 (file)
index 0000000..3ac16ac
--- /dev/null
@@ -0,0 +1,19 @@
+#\r
+#   Domain name\r
+#\r
+domain          intel.com\r
+\r
+;\r
+;   Name Servers\r
+;\r
+nameserver      206.63.63.61\r
+nameserver      216.251.100.1\r
+\r
+; nameserver      10.248.2.1\r
+; nameserver      10.22.224.204\r
+\r
+#\r
+#   Enable debugging\r
+#\r
+#options         debug\r
+\r
diff --git a/StdLib/Efi/etc/services b/StdLib/Efi/etc/services
new file mode 100644 (file)
index 0000000..c95b1bf
--- /dev/null
@@ -0,0 +1,576 @@
+# Network services, Internet style
+#
+# Note that it is presently the policy of IANA to assign a single well-known
+# port number for both TCP and UDP; hence, officially ports have two entries
+# even if the protocol doesn't support UDP operations.
+#
+# Updated from http://www.iana.org/assignments/port-numbers and other
+# sources like http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/services .
+# New ports will be added on request if they have been officially assigned
+# by IANA and used in the real-world or are needed by a debian package.
+# If you need a huge list of used numbers please install the nmap package.
+
+tcpmux         1/tcp                           # TCP port service multiplexer
+echo           7/tcp
+echo           7/udp
+discard                9/tcp           sink null
+discard                9/udp           sink null
+systat         11/tcp          users
+daytime                13/tcp
+daytime                13/udp
+netstat                15/tcp
+qotd           17/tcp          quote
+msp            18/tcp                          # message send protocol
+msp            18/udp
+chargen                19/tcp          ttytst source
+chargen                19/udp          ttytst source
+ftp-data       20/tcp
+ftp            21/tcp
+fsp            21/udp          fspd
+ssh            22/tcp                          # SSH Remote Login Protocol
+ssh            22/udp
+telnet         23/tcp
+smtp           25/tcp          mail
+time           37/tcp          timserver
+time           37/udp          timserver
+rlp            39/udp          resource        # resource location
+nameserver     42/tcp          name            # IEN 116
+whois          43/tcp          nicname
+tacacs         49/tcp                          # Login Host Protocol (TACACS)
+tacacs         49/udp
+re-mail-ck     50/tcp                          # Remote Mail Checking Protocol
+re-mail-ck     50/udp
+domain         53/tcp                          # name-domain server
+domain         53/udp
+mtp            57/tcp                          # deprecated
+tacacs-ds      65/tcp                          # TACACS-Database Service
+tacacs-ds      65/udp
+bootps         67/tcp                          # BOOTP server
+bootps         67/udp
+bootpc         68/tcp                          # BOOTP client
+bootpc         68/udp
+tftp           69/udp
+gopher         70/tcp                          # Internet Gopher
+gopher         70/udp
+rje            77/tcp          netrjs
+finger         79/tcp
+www            80/tcp          http            # WorldWideWeb HTTP
+www            80/udp                          # HyperText Transfer Protocol
+link           87/tcp          ttylink
+kerberos       88/tcp          kerberos5 krb5 kerberos-sec     # Kerberos v5
+kerberos       88/udp          kerberos5 krb5 kerberos-sec     # Kerberos v5
+supdup         95/tcp
+hostnames      101/tcp         hostname        # usually from sri-nic
+iso-tsap       102/tcp         tsap            # part of ISODE
+acr-nema       104/tcp         dicom           # Digital Imag. & Comm. 300
+acr-nema       104/udp         dicom           # Digital Imag. & Comm. 300
+csnet-ns       105/tcp         cso-ns          # also used by CSO name server
+csnet-ns       105/udp         cso-ns
+rtelnet                107/tcp                         # Remote Telnet
+rtelnet                107/udp
+pop2           109/tcp         postoffice pop-2 # POP version 2
+pop2           109/udp         pop-2
+pop3           110/tcp         pop-3           # POP version 3
+pop3           110/udp         pop-3
+sunrpc         111/tcp         portmapper      # RPC 4.0 portmapper
+sunrpc         111/udp         portmapper
+auth           113/tcp         authentication tap ident
+sftp           115/tcp
+uucp-path      117/tcp
+nntp           119/tcp         readnews untp   # USENET News Transfer Protocol
+ntp            123/tcp
+ntp            123/udp                         # Network Time Protocol
+pwdgen         129/tcp                         # PWDGEN service
+pwdgen         129/udp                         # PWDGEN service
+loc-srv                135/tcp         epmap           # Location Service
+loc-srv                135/udp         epmap
+netbios-ns     137/tcp                         # NETBIOS Name Service
+netbios-ns     137/udp
+netbios-dgm    138/tcp                         # NETBIOS Datagram Service
+netbios-dgm    138/udp
+netbios-ssn    139/tcp                         # NETBIOS session service
+netbios-ssn    139/udp
+imap2          143/tcp         imap            # Interim Mail Access P 2 and 4
+imap2          143/udp         imap
+snmp           161/tcp                         # Simple Net Mgmt Protocol
+snmp           161/udp                         # Simple Net Mgmt Protocol
+snmp-trap      162/tcp         snmptrap        # Traps for SNMP
+snmp-trap      162/udp         snmptrap        # Traps for SNMP
+cmip-man       163/tcp                         # ISO mgmt over IP (CMOT)
+cmip-man       163/udp
+cmip-agent     164/tcp
+cmip-agent     164/udp
+mailq          174/tcp                 # Mailer transport queue for Zmailer
+mailq          174/udp                 # Mailer transport queue for Zmailer
+xdmcp          177/tcp                         # X Display Mgr. Control Proto
+xdmcp          177/udp
+nextstep       178/tcp         NeXTStep NextStep       # NeXTStep window
+nextstep       178/udp         NeXTStep NextStep       #  server
+bgp            179/tcp                         # Border Gateway Protocol
+bgp            179/udp
+prospero       191/tcp                         # Cliff Neuman's Prospero
+prospero       191/udp
+irc            194/tcp                         # Internet Relay Chat
+irc            194/udp
+smux           199/tcp                         # SNMP Unix Multiplexer
+smux           199/udp
+at-rtmp                201/tcp                         # AppleTalk routing
+at-rtmp                201/udp
+at-nbp         202/tcp                         # AppleTalk name binding
+at-nbp         202/udp
+at-echo                204/tcp                         # AppleTalk echo
+at-echo                204/udp
+at-zis         206/tcp                         # AppleTalk zone information
+at-zis         206/udp
+qmtp           209/tcp                         # Quick Mail Transfer Protocol
+qmtp           209/udp                         # Quick Mail Transfer Protocol
+z3950          210/tcp         wais            # NISO Z39.50 database
+z3950          210/udp         wais
+ipx            213/tcp                         # IPX
+ipx            213/udp
+imap3          220/tcp                         # Interactive Mail Access
+imap3          220/udp                         # Protocol v3
+pawserv                345/tcp                         # Perf Analysis Workbench
+pawserv                345/udp
+zserv          346/tcp                         # Zebra server
+zserv          346/udp
+fatserv                347/tcp                         # Fatmen Server
+fatserv                347/udp
+rpc2portmap    369/tcp
+rpc2portmap    369/udp                         # Coda portmapper
+codaauth2      370/tcp
+codaauth2      370/udp                         # Coda authentication server
+clearcase      371/tcp         Clearcase
+clearcase      371/udp         Clearcase
+ulistserv      372/tcp                         # UNIX Listserv
+ulistserv      372/udp
+ldap           389/tcp                 # Lightweight Directory Access Protocol
+ldap           389/udp
+imsp           406/tcp                 # Interactive Mail Support Protocol
+imsp           406/udp
+https          443/tcp                         # http protocol over TLS/SSL
+https          443/udp
+snpp           444/tcp                         # Simple Network Paging Protocol
+snpp           444/udp
+microsoft-ds   445/tcp                         # Microsoft Naked CIFS
+microsoft-ds   445/udp
+kpasswd                464/tcp
+kpasswd                464/udp
+saft           487/tcp                 # Simple Asynchronous File Transfer
+saft           487/udp
+isakmp         500/tcp                 # IPsec - Internet Security Association
+isakmp         500/udp                 #  and Key Management Protocol
+rtsp           554/tcp                 # Real Time Stream Control Protocol
+rtsp           554/udp                 # Real Time Stream Control Protocol
+nqs            607/tcp                         # Network Queuing system
+nqs            607/udp
+npmp-local     610/tcp         dqs313_qmaster          # npmp-local / DQS
+npmp-local     610/udp         dqs313_qmaster
+npmp-gui       611/tcp         dqs313_execd            # npmp-gui / DQS
+npmp-gui       611/udp         dqs313_execd
+hmmp-ind       612/tcp         dqs313_intercell        # HMMP Indication / DQS
+hmmp-ind       612/udp         dqs313_intercell
+qmqp           628/tcp
+qmqp           628/udp
+ipp            631/tcp                         # Internet Printing Protocol
+ipp            631/udp
+#
+# UNIX specific services
+#
+exec           512/tcp
+biff           512/udp         comsat
+login          513/tcp
+who            513/udp         whod
+shell          514/tcp         cmd             # no passwords used
+syslog         514/udp
+printer                515/tcp         spooler         # line printer spooler
+talk           517/udp
+ntalk          518/udp
+route          520/udp         router routed   # RIP
+timed          525/udp         timeserver
+tempo          526/tcp         newdate
+courier                530/tcp         rpc
+conference     531/tcp         chat
+netnews                532/tcp         readnews
+netwall                533/udp                         # for emergency broadcasts
+gdomap         538/tcp                         # GNUstep distributed objects
+gdomap         538/udp
+uucp           540/tcp         uucpd           # uucp daemon
+klogin         543/tcp                         # Kerberized `rlogin' (v5)
+kshell         544/tcp         krcmd           # Kerberized `rsh' (v5)
+afpovertcp     548/tcp                         # AFP over TCP
+afpovertcp     548/udp
+remotefs       556/tcp         rfs_server rfs  # Brunhoff remote filesystem
+nntps          563/tcp         snntp           # NNTP over SSL
+nntps          563/udp         snntp
+submission     587/tcp                         # Submission [RFC4409]
+submission     587/udp
+ldaps          636/tcp                         # LDAP over SSL
+ldaps          636/udp
+tinc           655/tcp                         # tinc control port
+tinc           655/udp
+silc           706/tcp
+silc           706/udp
+kerberos-adm   749/tcp                         # Kerberos `kadmin' (v5)
+#
+webster                765/tcp                         # Network dictionary
+webster                765/udp
+rsync          873/tcp
+rsync          873/udp
+ftps-data      989/tcp                         # FTP over SSL (data)
+ftps           990/tcp
+telnets                992/tcp                         # Telnet over SSL
+telnets                992/udp
+imaps          993/tcp                         # IMAP over SSL
+imaps          993/udp
+ircs           994/tcp                         # IRC over SSL
+ircs           994/udp
+pop3s          995/tcp                         # POP-3 over SSL
+pop3s          995/udp
+#
+# From ``Assigned Numbers'':
+#
+#> The Registered Ports are not controlled by the IANA and on most systems
+#> can be used by ordinary user processes or programs executed by ordinary
+#> users.
+#
+#> Ports are used in the TCP [45,106] to name the ends of logical
+#> connections which carry long term conversations.  For the purpose of
+#> providing services to unknown callers, a service contact port is
+#> defined.  This list specifies the port used by the server process as its
+#> contact port.  While the IANA can not control uses of these ports it
+#> does register or list uses of these ports as a convienence to the
+#> community.
+#
+socks          1080/tcp                        # socks proxy server
+socks          1080/udp
+proofd         1093/tcp
+proofd         1093/udp
+rootd          1094/tcp
+rootd          1094/udp
+openvpn                1194/tcp
+openvpn                1194/udp
+rmiregistry    1099/tcp                        # Java RMI Registry
+rmiregistry    1099/udp
+kazaa          1214/tcp
+kazaa          1214/udp
+nessus         1241/tcp                        # Nessus vulnerability
+nessus         1241/udp                        #  assessment scanner
+lotusnote      1352/tcp        lotusnotes      # Lotus Note
+lotusnote      1352/udp        lotusnotes
+ms-sql-s       1433/tcp                        # Microsoft SQL Server
+ms-sql-s       1433/udp
+ms-sql-m       1434/tcp                        # Microsoft SQL Monitor
+ms-sql-m       1434/udp
+ingreslock     1524/tcp
+ingreslock     1524/udp
+prospero-np    1525/tcp                        # Prospero non-privileged
+prospero-np    1525/udp
+datametrics    1645/tcp        old-radius
+datametrics    1645/udp        old-radius
+sa-msg-port    1646/tcp        old-radacct
+sa-msg-port    1646/udp        old-radacct
+kermit         1649/tcp
+kermit         1649/udp
+l2f            1701/tcp        l2tp
+l2f            1701/udp        l2tp
+radius         1812/tcp
+radius         1812/udp
+radius-acct    1813/tcp        radacct         # Radius Accounting
+radius-acct    1813/udp        radacct
+msnp           1863/tcp                        # MSN Messenger
+msnp           1863/udp
+unix-status    1957/tcp                        # remstats unix-status server
+log-server     1958/tcp                        # remstats log server
+remoteping     1959/tcp                        # remstats remoteping server
+cisco-sccp     2000/tcp        sieve           # Cisco SCCP
+cisco-sccp     2000/udp
+search         2010/tcp        ndtp
+pipe_server    2010/tcp
+nfs            2049/tcp                        # Network File System
+nfs            2049/udp                        # Network File System
+gnunet         2086/tcp
+gnunet         2086/udp
+rtcm-sc104     2101/tcp                        # RTCM SC-104 IANA 1/29/99
+rtcm-sc104     2101/udp
+gsigatekeeper  2119/tcp
+gsigatekeeper  2119/udp
+gris           2135/tcp                # Grid Resource Information Server
+gris           2135/udp                # Grid Resource Information Server
+cvspserver     2401/tcp                        # CVS client/server operations
+cvspserver     2401/udp
+venus          2430/tcp                        # codacon port
+venus          2430/udp                        # Venus callback/wbc interface
+venus-se       2431/tcp                        # tcp side effects
+venus-se       2431/udp                        # udp sftp side effect
+codasrv                2432/tcp                        # not used
+codasrv                2432/udp                        # server port
+codasrv-se     2433/tcp                        # tcp side effects
+codasrv-se     2433/udp                        # udp sftp side effect
+mon            2583/tcp                        # MON traps
+mon            2583/udp
+dict           2628/tcp                        # Dictionary server
+dict           2628/udp
+gsiftp         2811/tcp
+gsiftp         2811/udp
+gpsd           2947/tcp
+gpsd           2947/udp
+gds_db         3050/tcp                        # InterBase server
+gds_db         3050/udp
+icpv2          3130/tcp        icp             # Internet Cache Protocol
+icpv2          3130/udp        icp
+mysql          3306/tcp
+mysql          3306/udp
+nut            3493/tcp                        # Network UPS Tools
+nut            3493/udp
+distcc         3632/tcp                        # distributed compiler
+distcc         3632/udp
+daap           3689/tcp                        # Digital Audio Access Protocol
+daap           3689/udp
+svn            3690/tcp        subversion      # Subversion protocol
+svn            3690/udp        subversion
+suucp          4031/tcp                        # UUCP over SSL
+suucp          4031/udp                        # UUCP over SSL
+sysrqd         4094/tcp                        # sysrq daemon
+sysrqd         4094/udp                        # sysrq daemon
+remctl         4373/tcp                # Remote Authenticated Command Service
+remctl         4373/udp                # Remote Authenticated Command Service
+iax            4569/tcp                        # Inter-Asterisk eXchange
+iax            4569/udp
+radmin-port    4899/tcp                        # RAdmin Port
+radmin-port    4899/udp
+rfe            5002/udp                        # Radio Free Ethernet
+rfe            5002/tcp
+mmcc           5050/tcp        # multimedia conference control tool (Yahoo IM)
+mmcc           5050/udp
+sip            5060/tcp                        # Session Initiation Protocol
+sip            5060/udp
+sip-tls                5061/tcp
+sip-tls                5061/udp
+aol            5190/tcp                        # AIM
+aol            5190/udp
+xmpp-client    5222/tcp        jabber-client   # Jabber Client Connection
+xmpp-client    5222/udp        jabber-client
+xmpp-server    5269/tcp        jabber-server   # Jabber Server Connection
+xmpp-server    5269/udp        jabber-server
+cfengine       5308/tcp
+cfengine       5308/udp
+mdns           5353/tcp                        # Multicast DNS
+mdns           5353/udp                        # Multicast DNS
+postgresql     5432/tcp        postgres        # PostgreSQL Database
+postgresql     5432/udp        postgres
+freeciv                5556/tcp        rptp            # Freeciv gameplay
+freeciv                5556/udp
+amqp           5672/tcp
+amqp           5672/udp
+amqp           5672/sctp
+ggz            5688/tcp                        # GGZ Gaming Zone
+ggz            5688/udp                        # GGZ Gaming Zone
+x11            6000/tcp        x11-0           # X Window System
+x11            6000/udp        x11-0
+x11-1          6001/tcp
+x11-1          6001/udp
+x11-2          6002/tcp
+x11-2          6002/udp
+x11-3          6003/tcp
+x11-3          6003/udp
+x11-4          6004/tcp
+x11-4          6004/udp
+x11-5          6005/tcp
+x11-5          6005/udp
+x11-6          6006/tcp
+x11-6          6006/udp
+x11-7          6007/tcp
+x11-7          6007/udp
+gnutella-svc   6346/tcp                        # gnutella
+gnutella-svc   6346/udp
+gnutella-rtr   6347/tcp                        # gnutella
+gnutella-rtr   6347/udp
+sge_qmaster    6444/tcp                        # Grid Engine Qmaster Service
+sge_qmaster    6444/udp                        # Grid Engine Qmaster Service
+sge_execd      6445/tcp                        # Grid Engine Execution Service
+sge_execd      6445/udp                        # Grid Engine Execution Service
+afs3-fileserver 7000/tcp       bbs             # file server itself
+afs3-fileserver 7000/udp       bbs
+afs3-callback  7001/tcp                        # callbacks to cache managers
+afs3-callback  7001/udp
+afs3-prserver  7002/tcp                        # users & groups database
+afs3-prserver  7002/udp
+afs3-vlserver  7003/tcp                        # volume location database
+afs3-vlserver  7003/udp
+afs3-kaserver  7004/tcp                        # AFS/Kerberos authentication
+afs3-kaserver  7004/udp
+afs3-volser    7005/tcp                        # volume managment server
+afs3-volser    7005/udp
+afs3-errors    7006/tcp                        # error interpretation service
+afs3-errors    7006/udp
+afs3-bos       7007/tcp                        # basic overseer process
+afs3-bos       7007/udp
+afs3-update    7008/tcp                        # server-to-server updater
+afs3-update    7008/udp
+afs3-rmtsys    7009/tcp                        # remote cache manager service
+afs3-rmtsys    7009/udp
+font-service   7100/tcp        xfs             # X Font Service
+font-service   7100/udp        xfs
+http-alt       8080/tcp        webcache        # WWW caching service
+http-alt       8080/udp                        # WWW caching service
+bacula-dir     9101/tcp                        # Bacula Director
+bacula-dir     9101/udp
+bacula-fd      9102/tcp                        # Bacula File Daemon
+bacula-fd      9102/udp
+bacula-sd      9103/tcp                        # Bacula Storage Daemon
+bacula-sd      9103/udp
+xmms2          9667/tcp        # Cross-platform Music Multiplexing System
+xmms2          9667/udp        # Cross-platform Music Multiplexing System
+amanda         10080/tcp                       # amanda backup services
+amanda         10080/udp
+hkp            11371/tcp                       # OpenPGP HTTP Keyserver
+hkp            11371/udp                       # OpenPGP HTTP Keyserver
+bprd           13720/tcp                       # VERITAS NetBackup
+bprd           13720/udp
+bpdbm          13721/tcp                       # VERITAS NetBackup
+bpdbm          13721/udp
+bpjava-msvc    13722/tcp                       # BP Java MSVC Protocol
+bpjava-msvc    13722/udp
+vnetd          13724/tcp                       # Veritas Network Utility
+vnetd          13724/udp
+bpcd           13782/tcp                       # VERITAS NetBackup
+bpcd           13782/udp
+vopied         13783/tcp                       # VERITAS NetBackup
+vopied         13783/udp
+wnn6           22273/tcp                       # wnn6
+wnn6           22273/udp
+
+#
+# Datagram Delivery Protocol services
+#
+rtmp           1/ddp                   # Routing Table Maintenance Protocol
+nbp            2/ddp                   # Name Binding Protocol
+echo           4/ddp                   # AppleTalk Echo Protocol
+zip            6/ddp                   # Zone Information Protocol
+
+#=========================================================================
+# The remaining port numbers are not as allocated by IANA.
+#=========================================================================
+
+# Kerberos (Project Athena/MIT) services
+# Note that these are for Kerberos v4, and are unofficial.  Sites running
+# v4 should uncomment these and comment out the v5 entries above.
+#
+kerberos4      750/udp         kerberos-iv kdc # Kerberos (server)
+kerberos4      750/tcp         kerberos-iv kdc
+kerberos_master        751/udp                         # Kerberos authentication
+kerberos_master        751/tcp
+passwd_server  752/udp                         # Kerberos passwd server
+krb_prop       754/tcp         krb5_prop hprop # Kerberos slave propagation
+krbupdate      760/tcp         kreg            # Kerberos registration
+swat           901/tcp                         # swat
+kpop           1109/tcp                        # Pop with Kerberos
+knetd          2053/tcp                        # Kerberos de-multiplexor
+zephyr-srv     2102/udp                        # Zephyr server
+zephyr-clt     2103/udp                        # Zephyr serv-hm connection
+zephyr-hm      2104/udp                        # Zephyr hostmanager
+eklogin                2105/tcp                        # Kerberos encrypted rlogin
+# Hmmm. Are we using Kv4 or Kv5 now? Worrying.
+# The following is probably Kerberos v5  --- ajt@debian.org (11/02/2000)
+kx             2111/tcp                        # X over Kerberos
+iprop          2121/tcp                        # incremental propagation
+#
+# Unofficial but necessary (for NetBSD) services
+#
+supfilesrv     871/tcp                         # SUP server
+supfiledbg     1127/tcp                        # SUP debugging
+
+#
+# Services added for the Debian GNU/Linux distribution
+#
+linuxconf      98/tcp                          # LinuxConf
+poppassd       106/tcp                         # Eudora
+poppassd       106/udp
+ssmtp          465/tcp         smtps           # SMTP over SSL
+moira_db       775/tcp                         # Moira database
+moira_update   777/tcp                         # Moira update protocol
+moira_ureg     779/udp                         # Moira user registration
+spamd          783/tcp                         # spamassassin daemon
+omirr          808/tcp         omirrd          # online mirror
+omirr          808/udp         omirrd
+customs                1001/tcp                        # pmake customs server
+customs                1001/udp
+skkserv                1178/tcp                        # skk jisho server port
+predict                1210/udp                        # predict -- satellite tracking
+rmtcfg         1236/tcp                        # Gracilis Packeten remote config server
+wipld          1300/tcp                        # Wipl network monitor
+xtel           1313/tcp                        # french minitel
+xtelw          1314/tcp                        # french minitel
+support                1529/tcp                        # GNATS
+cfinger                2003/tcp                        # GNU Finger
+frox           2121/tcp                        # frox: caching ftp proxy
+ninstall       2150/tcp                        # ninstall service
+ninstall       2150/udp
+zebrasrv       2600/tcp                        # zebra service
+zebra          2601/tcp                        # zebra vty
+ripd           2602/tcp                        # ripd vty (zebra)
+ripngd         2603/tcp                        # ripngd vty (zebra)
+ospfd          2604/tcp                        # ospfd vty (zebra)
+bgpd           2605/tcp                        # bgpd vty (zebra)
+ospf6d         2606/tcp                        # ospf6d vty (zebra)
+ospfapi                2607/tcp                        # OSPF-API
+isisd          2608/tcp                        # ISISd vty (zebra)
+afbackup       2988/tcp                        # Afbackup system
+afbackup       2988/udp
+afmbackup      2989/tcp                        # Afmbackup system
+afmbackup      2989/udp
+xtell          4224/tcp                        # xtell server
+fax            4557/tcp                        # FAX transmission service (old)
+hylafax                4559/tcp                        # HylaFAX client-server protocol (new)
+distmp3                4600/tcp                        # distmp3host daemon
+munin          4949/tcp        lrrd            # Munin
+enbd-cstatd    5051/tcp                        # ENBD client statd
+enbd-sstatd    5052/tcp                        # ENBD server statd
+pcrd           5151/tcp                        # PCR-1000 Daemon
+noclog         5354/tcp                        # noclogd with TCP (nocol)
+noclog         5354/udp                        # noclogd with UDP (nocol)
+hostmon                5355/tcp                        # hostmon uses TCP (nocol)
+hostmon                5355/udp                        # hostmon uses UDP (nocol)
+rplay          5555/udp                        # RPlay audio service
+nsca           5667/tcp                        # Nagios Agent - NSCA
+mrtd           5674/tcp                        # MRT Routing Daemon
+bgpsim         5675/tcp                        # MRT Routing Simulator
+canna          5680/tcp                        # cannaserver
+sane-port      6566/tcp        sane saned      # SANE network scanner daemon
+ircd           6667/tcp                        # Internet Relay Chat
+zope-ftp       8021/tcp                        # zope management by ftp
+tproxy         8081/tcp                        # Transparent Proxy
+omniorb                8088/tcp                        # OmniORB
+omniorb                8088/udp
+clc-build-daemon 8990/tcp                      # Common lisp build daemon
+xinetd         9098/tcp
+mandelspawn    9359/udp        mandelbrot      # network mandelbrot
+git            9418/tcp                        # Git Version Control System
+zope           9673/tcp                        # zope server
+webmin         10000/tcp
+kamanda                10081/tcp                       # amanda backup services (Kerberos)
+kamanda                10081/udp
+amandaidx      10082/tcp                       # amanda backup services
+amidxtape      10083/tcp                       # amanda backup services
+smsqp          11201/tcp                       # Alamin SMS gateway
+smsqp          11201/udp
+xpilot         15345/tcp                       # XPilot Contact Port
+xpilot         15345/udp
+sgi-cmsd       17001/udp               # Cluster membership services daemon
+sgi-crsd       17002/udp
+sgi-gcd                17003/udp                       # SGI Group membership daemon
+sgi-cad                17004/tcp                       # Cluster Admin daemon
+isdnlog                20011/tcp                       # isdn logging system
+isdnlog                20011/udp
+vboxd          20012/tcp                       # voice box system
+vboxd          20012/udp
+binkp          24554/tcp                       # binkp fidonet protocol
+asp            27374/tcp                       # Address Search Protocol
+asp            27374/udp
+csync2         30865/tcp                       # cluster synchronization tool
+dircproxy      57000/tcp                       # Detachable IRC Proxy
+tfido          60177/tcp                       # fidonet EMSI over telnet
+fido           60179/tcp                       # fidonet EMSI over TCP
+
+# Local services
diff --git a/StdLib/EfiSocketLib/EfiSocketLib.inf b/StdLib/EfiSocketLib/EfiSocketLib.inf
new file mode 100644 (file)
index 0000000..9a30193
--- /dev/null
@@ -0,0 +1,56 @@
+#/** @file\r
+# Component description file for the EFI socket library.\r
+#\r
+# This module implements the socket layer.\r
+# Copyright (c) 2011, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = EfiSocketLib\r
+  FILE_GUID                      = C33E0B7C-9D0F-41df-BDFD-08F5E4C39EE8\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = EfiSocketLib\r
+  CONSTRUCTOR                    = EslConstructor\r
+  DESTRUCTOR                     = EslDestructor\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  Init.c\r
+  Service.c\r
+  Socket.c\r
+  Tcp4.c\r
+  Udp4.c\r
+  UseEfiSocketLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  StdLib/StdLib.dec\r
+#  SocketPkg/SocketPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+\r
+[Protocols]\r
+  gEfiTcp4ProtocolGuid\r
+  gEfiTcp4ServiceBindingProtocolGuid\r
+  gEfiUdp4ProtocolGuid\r
+  gEfiUdp4ServiceBindingProtocolGuid\r
+  gEfiSocketProtocolGuid\r
+  gEfiSocketServiceBindingProtocolGuid\r
diff --git a/StdLib/EfiSocketLib/Init.c b/StdLib/EfiSocketLib/Init.c
new file mode 100644 (file)
index 0000000..7a1b89d
--- /dev/null
@@ -0,0 +1,87 @@
+/** @file\r
+  Implement the constructor and destructor for the EFI socket library\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <socket.h>\r
+\r
+\r
+/**\r
+  EFI Socket Library Constructor\r
+\r
+  @retval EFI_SUCCESS       The initialization was successful\r
+\r
+ **/\r
+EFI_STATUS\r
+EFIAPI\r
+EslConstructor (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Call the image dependent constructor if available\r
+  //\r
+  if ( NULL != mpfnEslConstructor ) {\r
+    Status = mpfnEslConstructor ( );\r
+  }\r
+\r
+  //\r
+  //  Return the constructor status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  EFI Socket Library Destructor\r
+\r
+  @retval EFI_SUCCESS       The shutdown was successful\r
+\r
+ **/\r
+EFI_STATUS\r
+EFIAPI\r
+EslDestructor (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Call the image dependent destructor if available\r
+  //\r
+  if ( NULL != mpfnEslDestructor ) {\r
+    Status = mpfnEslDestructor ( );\r
+  }\r
+\r
+  //\r
+  //  Return the constructor status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
diff --git a/StdLib/EfiSocketLib/Service.c b/StdLib/EfiSocketLib/Service.c
new file mode 100644 (file)
index 0000000..49c8884
--- /dev/null
@@ -0,0 +1,529 @@
+/** @file\r
+  Connect to and disconnect from the various network layers\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Socket.h"\r
+\r
+EFI_TCP4_PROTOCOL * mpEfiTcpClose4 [ 1024 ];\r
+\r
+\r
+/**\r
+  Connect to the network service bindings\r
+\r
+  Walk the network service protocols on the controller handle and\r
+  locate any that are not in use.  Create service structures to\r
+  manage the service binding for the socket driver.\r
+\r
+  @param [in] BindingHandle    Handle for protocol binding.\r
+  @param [in] Controller       Handle of device to work with.\r
+\r
+  @retval EFI_SUCCESS          This driver is added to Controller.\r
+  @retval other                This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslServiceConnect (\r
+  IN EFI_HANDLE BindingHandle,\r
+  IN EFI_HANDLE Controller\r
+  )\r
+{\r
+  BOOLEAN bInUse;\r
+  UINTN LengthInBytes;\r
+  CONST DT_SOCKET_BINDING * pEnd;\r
+  VOID * pJunk;\r
+  VOID * pInterface;\r
+  DT_SERVICE * pService;\r
+  CONST DT_SOCKET_BINDING * pSocketBinding;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume the list is empty\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+  bInUse = FALSE;\r
+\r
+  //\r
+  //  Walk the list of network connection points\r
+  //\r
+  pSocketBinding = &cEslSocketBinding[0];\r
+  pEnd = &pSocketBinding[ cEslSocketBindingEntries ];\r
+  while ( pEnd > pSocketBinding ) {\r
+    //\r
+    //  Determine if the controller supports the network protocol\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    pSocketBinding->pNetworkBinding,\r
+                    &pInterface,\r
+                    BindingHandle,\r
+                    Controller,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Determine if the socket layer is already connected\r
+      //\r
+      Status = gBS->OpenProtocol (\r
+                      Controller,\r
+                      (EFI_GUID *)pSocketBinding->pTagGuid,\r
+                      &pJunk,\r
+                      BindingHandle,\r
+                      Controller,\r
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                      );\r
+      if ( EFI_UNSUPPORTED == Status ) {\r
+        //\r
+        //  Allocate a service structure since the tag is not present\r
+        //\r
+        LengthInBytes = sizeof ( *pService );\r
+        Status = gBS->AllocatePool (\r
+                        EfiRuntimeServicesData,\r
+                        LengthInBytes,\r
+                        (VOID **) &pService\r
+                        );\r
+        if ( !EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
+                    "0x%08x: Allocate pService, %d bytes\r\n",\r
+                    pService,\r
+                    LengthInBytes ));\r
+\r
+          //\r
+          //  Set the structure signature and service binding\r
+          //\r
+          ZeroMem ( pService, LengthInBytes );\r
+          pService->Signature = SERVICE_SIGNATURE;\r
+          pService->pSocketBinding = pSocketBinding;\r
+          pService->Controller = Controller;\r
+          pService->pInterface = pInterface;\r
+\r
+          //\r
+          //  Mark the controller in use\r
+          //\r
+          if ( !bInUse ) {\r
+            Status = gBS->InstallMultipleProtocolInterfaces (\r
+                            &Controller,\r
+                            &gEfiCallerIdGuid,\r
+                            NULL,\r
+                            NULL\r
+                            );\r
+            if ( !EFI_ERROR ( Status )) {\r
+              DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                        "Installed: gEfiCallerIdGuid on   0x%08x\r\n",\r
+                        Controller ));\r
+              bInUse = TRUE;\r
+            }\r
+            else {\r
+              if ( EFI_INVALID_PARAMETER == Status ) {\r
+                Status = EFI_SUCCESS;\r
+              }\r
+            }\r
+          }\r
+          if ( !EFI_ERROR ( Status )) {\r
+            //\r
+            //  Mark the network service protocol in use\r
+            //\r
+            Status = gBS->InstallMultipleProtocolInterfaces (\r
+                            &Controller,\r
+                            pSocketBinding->pTagGuid,\r
+                            pService,\r
+                            NULL\r
+                            );\r
+            if ( !EFI_ERROR ( Status )) {\r
+              DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                        "Installed: %s TagGuid on   0x%08x\r\n",\r
+                        pSocketBinding->pName,\r
+                        Controller ));\r
+\r
+              //\r
+              //  Synchronize with the socket layer\r
+              //\r
+              RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+              //\r
+              //  Initialize the service\r
+              //\r
+              Status = pSocketBinding->pfnInitialize ( pService );\r
+\r
+              //\r
+              //  Release the socket layer synchronization\r
+              //\r
+              RESTORE_TPL ( TplPrevious );\r
+\r
+              //\r
+              //  Determine if the initialization was successful\r
+              //\r
+              if ( EFI_ERROR ( Status )) {\r
+                DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
+                          "ERROR - Failed to initialize service %s on 0x%08x, Status: %r\r\n",\r
+                          pSocketBinding->pName,\r
+                          Controller,\r
+                          Status ));\r
+\r
+                //\r
+                //  Free the network service binding if necessary\r
+                //\r
+                gBS->UninstallMultipleProtocolInterfaces (\r
+                          Controller,\r
+                          pSocketBinding->pTagGuid,\r
+                          pService,\r
+                          NULL );\r
+                DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                            "Removed:   %s TagGuid from 0x%08x\r\n",\r
+                            pSocketBinding->pName,\r
+                            Controller ));\r
+              }\r
+            }\r
+            else {\r
+              DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
+                        "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",\r
+                        pSocketBinding->pName,\r
+                        Controller,\r
+                        Status ));\r
+            }\r
+\r
+            if ( EFI_ERROR ( Status )) {\r
+              //\r
+              //  The controller is no longer in use\r
+              //\r
+              if ( bInUse ) {\r
+                gBS->UninstallMultipleProtocolInterfaces (\r
+                          Controller,\r
+                          &gEfiCallerIdGuid,\r
+                          NULL,\r
+                          NULL );\r
+                DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                            "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",\r
+                            Controller ));\r
+              }\r
+            }\r
+          }\r
+          else {\r
+            DEBUG (( DEBUG_ERROR | DEBUG_INIT,\r
+                      "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",\r
+                      Controller,\r
+                      Status ));\r
+          }\r
+\r
+          //\r
+          //  Release the service if necessary\r
+          //\r
+          if ( EFI_ERROR ( Status )) {\r
+            gBS->FreePool ( pService );\r
+            DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
+                      "0x%08x: Free pService, %d bytes\r\n",\r
+                      pService,\r
+                      sizeof ( *pService )));\r
+            pService = NULL;\r
+          }\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_ERROR | DEBUG_INIT,\r
+                    "ERROR - Failed service allocation, Status: %r\r\n",\r
+                    Status ));\r
+        }\r
+      }\r
+    }\r
+  \r
+    //\r
+    //  Set the next network protocol\r
+    //\r
+    pSocketBinding += 1;\r
+  }\r
+  \r
+  //\r
+  //  Display the driver start status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Shutdown the network connections to this controller by removing\r
+  NetworkInterfaceIdentifier protocol and closing the DevicePath\r
+  and PciIo protocols on Controller.\r
+\r
+  @param [in] BindingHandle    Handle for protocol binding.\r
+  @param [in] Controller           Handle of device to stop driver on.\r
+\r
+  @retval EFI_SUCCESS          This driver is removed Controller.\r
+  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.\r
+  @retval other                This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslServiceDisconnect (\r
+  IN  EFI_HANDLE BindingHandle,\r
+  IN  EFI_HANDLE Controller\r
+  )\r
+{\r
+  CONST DT_SOCKET_BINDING * pEnd;\r
+  DT_SERVICE * pService;\r
+  CONST DT_SOCKET_BINDING * pSocketBinding;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+  \r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Walk the list of network connection points in reverse order\r
+  //\r
+  pEnd = &cEslSocketBinding[0];\r
+  pSocketBinding = &pEnd[ cEslSocketBindingEntries ];\r
+  while ( pEnd < pSocketBinding ) {\r
+    //\r
+    //  Set the next network protocol\r
+    //\r
+    pSocketBinding -= 1;\r
+\r
+    //\r
+    //  Determine if the driver connected\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    (EFI_GUID *)pSocketBinding->pTagGuid,\r
+                    (VOID **)&pService,\r
+                    BindingHandle,\r
+                    Controller,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if ( !EFI_ERROR ( Status )) {\r
+\r
+      //\r
+      //  Synchronize with the socket layer\r
+      //\r
+      RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+      //\r
+      //  Shutdown the service\r
+      //\r
+      pSocketBinding->pfnShutdown ( pService );\r
+\r
+      //\r
+      //  Release the socket layer synchronization\r
+      //\r
+      RESTORE_TPL ( TplPrevious );\r
+\r
+      //\r
+      //  Break the driver connection\r
+      //\r
+      Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                Controller,\r
+                pSocketBinding->pTagGuid,\r
+                pService,\r
+                NULL );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
+                    "Removed:   %s TagGuid from 0x%08x\r\n",\r
+                    pSocketBinding->pName,\r
+                    Controller ));\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
+                    "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",\r
+                    pSocketBinding->pName,\r
+                    Controller,\r
+                    Status ));\r
+      }\r
+\r
+      //\r
+      //  Free the service structure\r
+      //\r
+      Status = gBS->FreePool ( pService );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
+                  "0x%08x: Free pService, %d bytes\r\n",\r
+                  pService,\r
+                  sizeof ( *pService )));\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
+                  "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",\r
+                  pService,\r
+                  Status ));\r
+      }\r
+      pService = NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  The controller is no longer in use\r
+  //\r
+  gBS->UninstallMultipleProtocolInterfaces (\r
+            Controller,\r
+            &gEfiCallerIdGuid,\r
+            NULL,\r
+            NULL );\r
+  DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+              "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",\r
+              Controller ));\r
+\r
+  //\r
+  //  The driver is disconnected from the network controller\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Display the driver start status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+/**\r
+Install the socket service\r
+\r
+@param [in] pImageHandle      Address of the image handle\r
+\r
+@retval EFI_SUCCESS     Service installed successfully\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslServiceInstall (\r
+  IN EFI_HANDLE * pImageHandle\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Install the socket service binding protocol\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  pImageHandle,\r
+                  &gEfiSocketServiceBindingProtocolGuid,\r
+                  &mEslLayer.ServiceBinding,\r
+                  NULL\r
+                  );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+              "Installed: gEfiSocketServiceBindingProtocolGuid on   0x%08x\r\n",\r
+              *pImageHandle ));\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
+              "ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",\r
+              Status ));\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+Initialize the service layer\r
+\r
+@param [in] ImageHandle       Handle for the image.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EslServiceLoad (\r
+  IN EFI_HANDLE ImageHandle\r
+  )\r
+{\r
+  DT_LAYER * pLayer;\r
+\r
+  //\r
+  //  Save the image handle\r
+  //\r
+  pLayer = &mEslLayer;\r
+  pLayer->Signature = LAYER_SIGNATURE;\r
+  pLayer->ImageHandle = ImageHandle;\r
+\r
+  //\r
+  //  Initialize the TCP4 close\r
+  //\r
+  pLayer->TcpCloseMax4 = DIM ( mpEfiTcpClose4 );\r
+  pLayer->ppTcpClose4 = mpEfiTcpClose4;\r
+\r
+  //\r
+  //  Connect the service binding protocol to the image handle\r
+  //\r
+  pLayer->ServiceBinding.CreateChild = EslSocketCreateChild;\r
+  pLayer->ServiceBinding.DestroyChild = EslSocketDestroyChild;\r
+}\r
+\r
+\r
+/**\r
+Uninstall the socket service\r
+\r
+@param [in] ImageHandle       Handle for the image.\r
+\r
+@retval EFI_SUCCESS     Service installed successfully\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslServiceUninstall (\r
+  IN EFI_HANDLE ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Install the socket service binding protocol\r
+  //\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+              ImageHandle,\r
+              &gEfiSocketServiceBindingProtocolGuid,\r
+              &mEslLayer.ServiceBinding,\r
+              NULL\r
+              );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
+                "Removed:   gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",\r
+                ImageHandle ));\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
+                "ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",\r
+                ImageHandle,\r
+                Status ));\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Shutdown the service layer\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EslServiceUnload (\r
+  VOID\r
+  )\r
+{\r
+  DT_LAYER * pLayer;\r
+\r
+  //\r
+  //  Undo the work by ServiceLoad\r
+  //\r
+  pLayer = &mEslLayer;\r
+  pLayer->ImageHandle = NULL;\r
+  pLayer->ServiceBinding.CreateChild = NULL;\r
+  pLayer->ServiceBinding.DestroyChild = NULL;\r
+}\r
diff --git a/StdLib/EfiSocketLib/Socket.c b/StdLib/EfiSocketLib/Socket.c
new file mode 100644 (file)
index 0000000..bad888c
--- /dev/null
@@ -0,0 +1,3091 @@
+/** @file\r
+  Implement the socket support for the socket layer.\r
+\r
+  Socket States:\r
+  * Bound - pSocket->PortList is not NULL\r
+  * Listen - AcceptWait event is not NULL\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Socket.h"\r
+\r
+\r
+/**\r
+  Socket driver connection points\r
+\r
+  List the network stack connection points for the socket driver.\r
+**/\r
+CONST DT_SOCKET_BINDING cEslSocketBinding [] = {\r
+  { L"Tcp4",\r
+    &gEfiTcp4ServiceBindingProtocolGuid,\r
+    &mEslTcp4ServiceGuid,\r
+    EslTcpInitialize4,\r
+    EslTcpShutdown4 },\r
+  { L"Udp4",\r
+    &gEfiUdp4ServiceBindingProtocolGuid,\r
+    &mEslUdp4ServiceGuid,\r
+    EslUdpInitialize4,\r
+    EslUdpShutdown4 }\r
+};\r
+\r
+CONST UINTN cEslSocketBindingEntries = DIM ( cEslSocketBinding );\r
+\r
+DT_LAYER mEslLayer;\r
+\r
+\r
+/**\r
+  Initialize an endpoint for network communication.\r
+\r
+  The ::Socket routine initializes the communication endpoint by providing\r
+  the support for the socket library function ::socket.  The\r
+  <a href="http://www.linuxhowtos.org/manpages/2/socket.htm">Linux</a>,\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html">POSIX</a>\r
+  and <a href="http://msdn.microsoft.com/en-us/library/ms740506(v=VS.85).aspx">Windows</a>\r
+  documentation for the socket routine are available online for reference.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [in] domain    Select the family of protocols for the client or server\r
+                        application.\r
+\r
+  @param [in] type      Specifies how to make the network connection.  The following values\r
+                        are supported:\r
+                        <ul>\r
+                          <li>\r
+                            SOCK_STREAM - Connect to TCP, provides a byte stream\r
+                            that is manipluated by read, recv, send and write.\r
+                          </li>\r
+                          <li>\r
+                            SOCK_SEQPACKET - Connect to TCP, provides sequenced packet stream\r
+                            that is manipulated by read, recv, send and write.\r
+                          </li>\r
+                          <li>\r
+                            SOCK_DGRAM - Connect to UDP, provides a datagram service that is\r
+                            manipulated by recvfrom and sendto.\r
+                          </li>\r
+                        </ul>\r
+\r
+  @param [in] protocol  Specifies the lower layer protocol to use.  The following\r
+                        values are supported:\r
+                        <ul>\r
+                          <li>IPPROTO_TCP</li> - This value must be combined with SOCK_STREAM.</li>\r
+                          <li>IPPROTO_UDP</li> - This value must be combined with SOCK_DGRAM.</li>\r
+                        </ul>\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+  @retval EFI_INVALID_PARAMETER - Invalid domain value, errno = EAFNOSUPPORT\r
+  @retval EFI_INVALID_PARAMETER - Invalid type value, errno = EINVAL\r
+  @retval EFI_INVALID_PARAMETER - Invalid protocol value, errno = EINVAL\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocket (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int domain,\r
+  IN int type,\r
+  IN int protocol,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  int errno;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Locate the socket\r
+  //\r
+  pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+  //\r
+  //  Set the default domain if necessary\r
+  //\r
+  if ( AF_UNSPEC == domain ) {\r
+    domain = AF_INET;\r
+  }\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  errno = 0;\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Use break instead of goto\r
+  //\r
+  for ( ; ; ) {\r
+    //\r
+    //  Validate the domain value\r
+    //\r
+    if (( AF_INET != domain )\r
+      && ( AF_LOCAL != domain ))\r
+    {\r
+      DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,\r
+                "ERROR - Invalid domain value" ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      errno = EAFNOSUPPORT;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Set the default type if necessary\r
+    //\r
+    if ( 0 == type ) {\r
+      type = SOCK_STREAM;\r
+    }\r
+\r
+    //\r
+    //  Validate the type value\r
+    //\r
+    if (( SOCK_STREAM == type )\r
+      || ( SOCK_SEQPACKET == type )) {\r
+      //\r
+      //  Set the default protocol if necessary\r
+      //\r
+      if ( 0 == protocol ) {\r
+        protocol = IPPROTO_TCP;\r
+      }\r
+    }\r
+    else if ( SOCK_DGRAM == type ) {\r
+      //\r
+      //  Set the default protocol if necessary\r
+      //\r
+      if ( 0 == protocol ) {\r
+        protocol = IPPROTO_UDP;\r
+      }\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,\r
+                "ERROR - Invalid type value" ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      errno = EINVAL;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Validate the protocol value\r
+    //\r
+    if (( IPPROTO_TCP != protocol )\r
+      && ( IPPROTO_UDP != protocol )) {\r
+      DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,\r
+                "ERROR - Invalid protocol value" ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      errno = EINVAL;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Save the socket attributes\r
+    //\r
+    pSocket->Domain = domain;\r
+    pSocket->Type = type;\r
+    pSocket->Protocol = protocol;\r
+\r
+    //\r
+    //  Done\r
+    //\r
+    break;\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    *pErrno = errno;\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Accept a network connection.\r
+\r
+  The SocketAccept routine waits for a network connection to the socket.\r
+  It is able to return the remote network address to the caller if\r
+  requested.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] pSockAddr       Address of a buffer to receive the remote\r
+                              network address.\r
+\r
+  @param [in, out] pSockAddrLength  Length in bytes of the address buffer.\r
+                                    On output specifies the length of the\r
+                                    remote network address.\r
+\r
+  @param [out] ppSocketProtocol Address of a buffer to receive the socket protocol\r
+                                instance associated with the new socket.\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS   New connection successfully created\r
+  @retval EFI_NOT_READY No connection is available\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketAccept (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN struct sockaddr * pSockAddr,\r
+  IN OUT socklen_t * pSockAddrLength,\r
+  IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pNewSocket;\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  pNewSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Validate the sockaddr\r
+    //\r
+    if (( NULL != pSockAddr )\r
+      && ( NULL == pSockAddrLength )) {\r
+      DEBUG (( DEBUG_ACCEPT,\r
+                "ERROR - pSockAddr is NULL!\r\n" ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      pSocket->errno = EFAULT;\r
+    }\r
+    else {\r
+      //\r
+      //  Synchronize with the socket layer\r
+      //\r
+      RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+      //\r
+      //  Verify that the socket is in the listen state\r
+      //\r
+      if ( SOCKET_STATE_LISTENING != pSocket->State ) {\r
+        DEBUG (( DEBUG_ACCEPT,\r
+                  "ERROR - Socket is not listening!\r\n" ));\r
+        Status = EFI_NOT_STARTED;\r
+        pSocket->errno = EOPNOTSUPP;\r
+      }\r
+      else {\r
+        //\r
+        //  Determine if a socket is available\r
+        //\r
+        if ( 0 == pSocket->FifoDepth ) {\r
+          //\r
+          //  No connections available\r
+          //  Determine if any ports are available\r
+          //\r
+          if ( NULL == pSocket->pPortList ) {\r
+            //\r
+            //  No ports available\r
+            //\r
+            Status = EFI_DEVICE_ERROR;\r
+            pSocket->errno = EINVAL;\r
+\r
+            //\r
+            //  Update the socket state\r
+            //\r
+            pSocket->State = SOCKET_STATE_NO_PORTS;\r
+          }\r
+          else {\r
+            //\r
+            //  Ports are available\r
+            //  No connection requests at this time\r
+            //\r
+            Status = EFI_NOT_READY;\r
+            pSocket->errno = EAGAIN;\r
+          }\r
+        }\r
+        else {\r
+  \r
+          //\r
+          //  Get the remote network address\r
+          //\r
+          pNewSocket = pSocket->pFifoHead;\r
+          ASSERT ( NULL != pNewSocket );\r
+          switch ( pSocket->Domain ) {\r
+          default:\r
+            DEBUG (( DEBUG_ACCEPT,\r
+                      "ERROR - Invalid socket address family: %d\r\n",\r
+                      pSocket->Domain ));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\r
+\r
+          case AF_INET:\r
+            //\r
+            //  Determine the connection point within the network stack\r
+            //\r
+            switch ( pSocket->Type ) {\r
+            default:\r
+              DEBUG (( DEBUG_ACCEPT,\r
+                        "ERROR - Invalid socket type: %d\r\n",\r
+                        pSocket->Type));\r
+              Status = EFI_INVALID_PARAMETER;\r
+              pSocket->errno = EADDRNOTAVAIL;\r
+              break;\r
+\r
+            case SOCK_STREAM:\r
+            case SOCK_SEQPACKET:\r
+              Status = EslTcpAccept4 ( pNewSocket,\r
+                                       pSockAddr,\r
+                                       pSockAddrLength );\r
+              break;\r
+\r
+  /*\r
+            case SOCK_DGRAM:\r
+              Status = UdpAccept4 ( pSocket );\r
+              break;\r
+  */\r
+            }\r
+            break;\r
+          }\r
+          if ( !EFI_ERROR ( Status )) {\r
+            //\r
+            //  Remove the new socket from the list\r
+            //\r
+            pSocket->pFifoHead = pNewSocket->pNextConnection;\r
+            if ( NULL == pSocket->pFifoHead ) {\r
+              pSocket->pFifoTail = NULL;\r
+            }\r
+\r
+            //\r
+            //  Account for this socket\r
+            //\r
+            pSocket->FifoDepth -= 1;\r
+\r
+            //\r
+            //  Update the new socket's state\r
+            //\r
+            pNewSocket->State = SOCKET_STATE_CONNECTED;\r
+            pNewSocket->bConfigured = TRUE;\r
+            DEBUG (( DEBUG_ACCEPT,\r
+                      "0x%08x: Socket connected\r\n",\r
+                      pNewSocket ));\r
+          }\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Release the socket layer synchronization\r
+      //\r
+      RESTORE_TPL ( TplPrevious );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the new socket\r
+  //\r
+  if (( NULL != ppSocketProtocol )\r
+    && ( NULL != pNewSocket )) {\r
+    *ppSocketProtocol = &pNewSocket->SocketProtocol;\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Allocate and initialize a DT_SOCKET structure.\r
+  \r
+  The ::SocketAllocate() function allocates a DT_SOCKET structure\r
+  and installs a protocol on ChildHandle.  If pChildHandle is a\r
+  pointer to NULL, then a new handle is created and returned in\r
+  pChildHandle.  If pChildHandle is not a pointer to NULL, then\r
+  the protocol installs on the existing pChildHandle.\r
+\r
+  @param [in, out] pChildHandle Pointer to the handle of the child to create.\r
+                                If it is NULL, then a new handle is created.\r
+                                If it is a pointer to an existing UEFI handle, \r
+                                then the protocol is added to the existing UEFI\r
+                                handle.\r
+  @param [in] DebugFlags        Flags for debug messages\r
+  @param [in, out] ppSocket     The buffer to receive the DT_SOCKET structure address.\r
+\r
+  @retval EFI_SUCCESS           The protocol was added to ChildHandle.\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources availabe to create\r
+                                the child\r
+  @retval other                 The child handle was not created\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslSocketAllocate (\r
+  IN OUT EFI_HANDLE * pChildHandle,\r
+  IN     UINTN DebugFlags,\r
+  IN OUT DT_SOCKET ** ppSocket\r
+  )\r
+{\r
+  UINTN LengthInBytes;\r
+  DT_LAYER * pLayer;\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Create a socket structure\r
+  //\r
+  LengthInBytes = sizeof ( *pSocket );\r
+  Status = gBS->AllocatePool (\r
+                  EfiRuntimeServicesData,\r
+                  LengthInBytes,\r
+                  (VOID **) &pSocket\r
+                  );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+              "0x%08x: Allocate pSocket, %d bytes\r\n",\r
+              pSocket,\r
+              LengthInBytes ));\r
+\r
+    //\r
+    //  Initialize the socket protocol\r
+    //\r
+    ZeroMem ( pSocket, LengthInBytes );\r
+\r
+    pSocket->Signature = SOCKET_SIGNATURE;\r
+    pSocket->SocketProtocol.pfnAccept = EslSocketAccept;\r
+    pSocket->SocketProtocol.pfnBind = EslSocketBind;\r
+    pSocket->SocketProtocol.pfnClosePoll = EslSocketClosePoll;\r
+    pSocket->SocketProtocol.pfnCloseStart = EslSocketCloseStart;\r
+    pSocket->SocketProtocol.pfnConnect = EslSocketConnect;\r
+    pSocket->SocketProtocol.pfnGetLocal = EslSocketGetLocalAddress;\r
+    pSocket->SocketProtocol.pfnGetPeer = EslSocketGetPeerAddress;\r
+    pSocket->SocketProtocol.pfnListen = EslSocketListen;\r
+    pSocket->SocketProtocol.pfnOptionGet = EslSocketOptionGet;\r
+    pSocket->SocketProtocol.pfnOptionSet = EslSocketOptionSet;\r
+    pSocket->SocketProtocol.pfnPoll = EslSocketPoll;\r
+    pSocket->SocketProtocol.pfnReceive = EslSocketReceive;\r
+    pSocket->SocketProtocol.pfnSend = EslSocketTransmit;\r
+    pSocket->SocketProtocol.pfnShutdown = EslSocketShutdown;\r
+    pSocket->SocketProtocol.pfnSocket = EslSocket;\r
+\r
+    pSocket->MaxRxBuf = MAX_RX_DATA;\r
+    pSocket->MaxTxBuf = MAX_TX_DATA;\r
+\r
+    //\r
+    //  Install the socket protocol on the specified handle\r
+    //\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    pChildHandle,\r
+                    &gEfiSocketProtocolGuid,\r
+                    &pSocket->SocketProtocol,\r
+                    NULL\r
+                    );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                "Installed: gEfiSocketProtocolGuid on   0x%08x\r\n",\r
+                *pChildHandle ));\r
+      pSocket->SocketProtocol.SocketHandle = *pChildHandle;\r
+\r
+      //\r
+      //  Synchronize with the socket layer\r
+      //\r
+      RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+      //\r
+      //  Add this socket to the list\r
+      //\r
+      pLayer = &mEslLayer;\r
+      pSocket->pNext = pLayer->pSocketList;\r
+      pLayer->pSocketList = pSocket;\r
+\r
+      //\r
+      //  Release the socket layer synchronization\r
+      //\r
+      RESTORE_TPL ( TplPrevious );\r
+\r
+      //\r
+      //  Return the socket structure address\r
+      //\r
+      *ppSocket = pSocket;\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+                "ERROR - Failed to install gEfiSocketProtocolGuid on 0x%08x, Status: %r\r\n",\r
+                *pChildHandle,\r
+                Status ));\r
+    }\r
+\r
+    //\r
+    //  Release the socket if necessary\r
+    //\r
+    if ( EFI_ERROR ( Status )) {\r
+      gBS->FreePool ( pSocket );\r
+      DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+                "0x%08x: Free pSocket, %d bytes\r\n",\r
+                pSocket,\r
+                sizeof ( *pSocket )));\r
+      pSocket = NULL;\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+              "ERROR - Failed socket allocation, Status: %r\r\n",\r
+              Status ));\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Bind a name to a socket.\r
+\r
+  The ::SocketBind routine connects a name to a socket on the local machine.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html">POSIX</a>\r
+  documentation for the bind routine is available online for reference.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] pSockAddr Address of a sockaddr structure that contains the\r
+                        connection point on the local machine.  An IPv4 address\r
+                        of INADDR_ANY specifies that the connection is made to\r
+                        all of the network stacks on the platform.  Specifying a\r
+                        specific IPv4 address restricts the connection to the\r
+                        network stack supporting that address.  Specifying zero\r
+                        for the port causes the network layer to assign a port\r
+                        number from the dynamic range.  Specifying a specific\r
+                        port number causes the network layer to use that port.\r
+\r
+  @param [in] SockAddrLen   Specifies the length in bytes of the sockaddr structure.\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketBind (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength,\r
+  OUT int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Validate the structure pointer\r
+    //\r
+    if ( NULL == pSockAddr ) {\r
+      DEBUG (( DEBUG_BIND,\r
+                "ERROR - pSockAddr is NULL!\r\n" ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      pSocket->errno = EFAULT;\r
+    }\r
+    else{\r
+      //\r
+      //  Validate the name length\r
+      //\r
+      if (( SockAddrLength < ( sizeof ( struct sockaddr ) - sizeof ( pSockAddr->sa_data )))\r
+        || ( pSockAddr->sa_len < ( sizeof ( struct sockaddr ) - sizeof ( pSockAddr->sa_data )))) {\r
+        DEBUG (( DEBUG_BIND,\r
+                  "ERROR - Invalid bind name length: %d, sa_len: %d\r\n",\r
+                  SockAddrLength,\r
+                  pSockAddr->sa_len ));\r
+        Status = EFI_INVALID_PARAMETER;\r
+        pSocket->errno = EINVAL;\r
+      }\r
+      else {\r
+        //\r
+        //  Set the socket address length\r
+        //\r
+        if ( SockAddrLength > pSockAddr->sa_len ) {\r
+          SockAddrLength = pSockAddr->sa_len;\r
+        }\r
+\r
+        //\r
+        //  Synchronize with the socket layer\r
+        //\r
+        RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+        //\r
+        //  Validate the local address\r
+        //\r
+        switch ( pSockAddr->sa_family ) {\r
+        default:\r
+          DEBUG (( DEBUG_BIND,\r
+                    "ERROR - Invalid bind address family: %d\r\n",\r
+                    pSockAddr->sa_family ));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+\r
+        case AF_INET:\r
+          //\r
+          //  Determine the connection point within the network stack\r
+          //\r
+          switch ( pSocket->Type ) {\r
+          default:\r
+            DEBUG (( DEBUG_BIND,\r
+                      "ERROR - Invalid socket type: %d\r\n",\r
+                      pSocket->Type));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\r
+\r
+          case SOCK_STREAM:\r
+          case SOCK_SEQPACKET:\r
+            Status = EslTcpBind4 ( pSocket,\r
+                                   pSockAddr,\r
+                                   SockAddrLength );\r
+            break;\r
+\r
+          case SOCK_DGRAM:\r
+            Status = EslUdpBind4 ( pSocket,\r
+                                   pSockAddr,\r
+                                   SockAddrLength );\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+\r
+        //\r
+        //  Mark this socket as bound if successful\r
+        //\r
+        if ( !EFI_ERROR ( Status )) {\r
+          pSocket->State = SOCKET_STATE_BOUND;\r
+        }\r
+\r
+        //\r
+        //  Release the socket layer synchronization\r
+        //\r
+        RESTORE_TPL ( TplPrevious );\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Determine if the socket is closed\r
+\r
+  Reverses the operations of the ::SocketAllocate() routine.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS     Socket successfully closed\r
+  @retval EFI_NOT_READY   Close still in progress\r
+  @retval EFI_ALREADY     Close operation already in progress\r
+  @retval Other           Failed to close the socket\r
+\r
+**/\r
+EFI_STATUS\r
+EslSocketClosePoll (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  int errno;\r
+  DT_LAYER * pLayer;\r
+  DT_SOCKET * pNextSocket;\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  errno = 0;\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Synchronize with the socket layer\r
+  //\r
+  RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+  //\r
+  //  Locate the socket\r
+  //\r
+  pLayer = &mEslLayer;\r
+  pNextSocket = pLayer->pSocketList;\r
+  pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+  while ( NULL != pNextSocket ) {\r
+    if ( pNextSocket == pSocket ) {\r
+      //\r
+      //  Determine if the socket is in the closing state\r
+      //\r
+      if ( SOCKET_STATE_CLOSED == pSocket->State ) {\r
+        //\r
+        //  Walk the list of ports\r
+        //\r
+        if ( NULL == pSocket->pPortList ) {\r
+          //\r
+          //  All the ports are closed\r
+          //  Close the WaitAccept event if necessary\r
+          //\r
+          if ( NULL != pSocket->WaitAccept ) {\r
+            Status = gBS->CloseEvent ( pSocket->WaitAccept );\r
+            if ( !EFI_ERROR ( Status )) {\r
+              DEBUG (( DEBUG_SOCKET | DEBUG_CLOSE | DEBUG_POOL,\r
+                        "0x%08x: Closed WaitAccept event\r\n",\r
+                        pSocket->WaitAccept ));\r
+              //\r
+              //  Return the transmit status\r
+              //\r
+              Status = pSocket->TxError;\r
+              if ( EFI_ERROR ( Status )) {\r
+                pSocket->errno = EIO;\r
+              }\r
+            }\r
+            else {\r
+              DEBUG (( DEBUG_ERROR | DEBUG_SOCKET | DEBUG_CLOSE | DEBUG_POOL,\r
+                        "ERROR - Failed to close the WaitAccept event, Status: %r\r\n",\r
+                        Status ));\r
+              ASSERT ( EFI_SUCCESS == Status );\r
+            }\r
+          }\r
+        }\r
+        else {\r
+          //\r
+          //  At least one port is still open\r
+          //\r
+          Status = EFI_NOT_READY;\r
+          errno = EAGAIN;\r
+        }\r
+      }\r
+      else {\r
+        //\r
+        //  SocketCloseStart was not called\r
+        //\r
+        Status = EFI_NOT_STARTED;\r
+        errno = EPERM;\r
+      }\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Set the next socket\r
+    //\r
+    pNextSocket = pNextSocket->pNext;\r
+  }\r
+\r
+  //\r
+  //  Handle the error case where the socket was already closed\r
+  //\r
+  if ( NULL == pSocket ) {\r
+    //\r
+    //  Socket not found\r
+    //\r
+    Status = EFI_NOT_FOUND;\r
+    errno = ENOTSOCK;\r
+  }\r
+\r
+  //\r
+  //  Release the socket layer synchronization\r
+  //\r
+  RESTORE_TPL ( TplPrevious );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    *pErrno = errno;\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Start the close operation on the socket\r
+\r
+  Start closing the socket by closing all of the ports.  Upon\r
+  completion, the ::SocketPoll() routine finishes closing the\r
+  socket.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [in] bCloseNow       Boolean to control close behavior\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS     Socket successfully closed\r
+  @retval EFI_NOT_READY   Close still in progress\r
+  @retval EFI_ALREADY     Close operation already in progress\r
+  @retval Other           Failed to close the socket\r
+\r
+**/\r
+EFI_STATUS\r
+EslSocketCloseStart (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN BOOLEAN bCloseNow,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  int errno;\r
+  DT_PORT * pNextPort;\r
+  DT_PORT * pPort;\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  errno = 0;\r
+\r
+  //\r
+  //  Synchronize with the socket layer\r
+  //\r
+  RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+  //\r
+  //  Determine if the socket is already closed\r
+  //\r
+  pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+  if ( SOCKET_STATE_CLOSED > pSocket->State ) {\r
+    //\r
+    //  Update the socket state\r
+    //\r
+    pSocket->State = SOCKET_STATE_CLOSED;\r
+\r
+    //\r
+    //  Walk the list of ports\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    while ( NULL != pPort ) {\r
+      //\r
+      //  Start closing the ports\r
+      //\r
+      pNextPort = pPort->pLinkSocket;\r
+      Status = pPort->pfnCloseStart ( pPort,\r
+                                      bCloseNow,\r
+                                      DEBUG_CLOSE | DEBUG_LISTEN | DEBUG_CONNECTION );\r
+      if (( EFI_SUCCESS != Status )\r
+        && ( EFI_NOT_READY != Status )) {\r
+        errno = EIO;\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Set the next port\r
+      //\r
+      pPort = pNextPort;\r
+    }\r
+\r
+    //\r
+    //  Attempt to finish closing the socket\r
+    //\r
+    if ( NULL == pPort ) {\r
+      Status = EslSocketClosePoll ( pSocketProtocol, &errno );\r
+    }\r
+  }\r
+  else {\r
+    Status = EFI_ALREADY_STARTED;\r
+    errno = EALREADY;\r
+  }\r
+\r
+  //\r
+  //  Release the socket layer synchronization\r
+  //\r
+  RESTORE_TPL ( TplPrevious );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    *pErrno = errno;\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Connect to a remote system via the network.\r
+\r
+  The ::SocketConnect routine attempts to establish a connection to a\r
+  socket on the local or remote system using the specified address.\r
+  The POSIX\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html">connect</a>\r
+  documentation is available online.\r
+\r
+  There are three states associated with a connection:\r
+  <ul>\r
+    <li>Not connected</li>\r
+    <li>Connection in progress</li>\r
+    <li>Connected</li>\r
+  </ul>\r
+  In the "Not connected" state, calls to ::connect start the connection\r
+  processing and update the state to "Connection in progress".  During\r
+  the "Connection in progress" state, connect polls for connection completion\r
+  and moves the state to "Connected" after the connection is established.\r
+  Note that these states are only visible when the file descriptor is marked\r
+  with O_NONBLOCK.  Also, the POLL_WRITE bit is set when the connection\r
+  completes and may be used by poll or select as an indicator to call\r
+  connect again.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] pSockAddr       Network address of the remote system.\r
+    \r
+  @param [in] SockAddrLength  Length in bytes of the network address.\r
+  \r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+  \r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketConnect (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+  \r
+  DEBUG (( DEBUG_CONNECT, "Entering SocketConnect\r\n" ));\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Validate the name length\r
+    //\r
+    if (( SockAddrLength < ( sizeof ( struct sockaddr ) - sizeof ( pSockAddr->sa_data )))\r
+      || ( pSockAddr->sa_len < ( sizeof ( struct sockaddr ) - sizeof ( pSockAddr->sa_data )))) {\r
+      DEBUG (( DEBUG_CONNECT,\r
+                "ERROR - Invalid bind name length: %d, sa_len: %d\r\n",\r
+                SockAddrLength,\r
+                pSockAddr->sa_len ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      pSocket->errno = EINVAL;\r
+    }\r
+    else {\r
+      //\r
+      //  Assume success\r
+      //\r
+      pSocket->errno = 0;\r
+\r
+      //\r
+      //  Set the socket address length\r
+      //\r
+      if ( SockAddrLength > pSockAddr->sa_len ) {\r
+        SockAddrLength = pSockAddr->sa_len;\r
+      }\r
+\r
+      //\r
+      //  Synchronize with the socket layer\r
+      //\r
+      RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+      //\r
+      //  Validate the socket state\r
+      //\r
+      switch ( pSocket->State ) {\r
+      default:\r
+        //\r
+        //  Wrong socket state\r
+        //\r
+        pSocket->errno = EIO;\r
+        Status = EFI_DEVICE_ERROR;\r
+        break;\r
+\r
+      case SOCKET_STATE_NOT_CONFIGURED:\r
+      case SOCKET_STATE_BOUND:\r
+        //\r
+        //  Validate the local address\r
+        //\r
+        switch ( pSockAddr->sa_family ) {\r
+        default:\r
+          DEBUG (( DEBUG_CONNECT,\r
+                    "ERROR - Invalid bind address family: %d\r\n",\r
+                    pSockAddr->sa_family ));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+\r
+        case AF_INET:\r
+          //\r
+          //  Determine the connection point within the network stack\r
+          //\r
+          switch ( pSocket->Type ) {\r
+          default:\r
+            DEBUG (( DEBUG_CONNECT,\r
+                      "ERROR - Invalid socket type: %d\r\n",\r
+                      pSocket->Type));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\r
+\r
+          case SOCK_STREAM:\r
+          case SOCK_SEQPACKET:\r
+            //\r
+            //  Start the connection processing\r
+            //\r
+            Status = EslTcpConnectStart4 ( pSocket,\r
+                                           pSockAddr,\r
+                                           SockAddrLength );\r
+\r
+            //\r
+            //  Set the next state if connecting\r
+            //\r
+            if ( EFI_NOT_READY == Status ) {\r
+              pSocket->State = SOCKET_STATE_CONNECTING;\r
+            }\r
+            break;\r
+\r
+          case SOCK_DGRAM:\r
+            Status = EslUdpConnect4 ( pSocket,\r
+                                      pSockAddr,\r
+                                      SockAddrLength );\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+        break;\r
+\r
+      case SOCKET_STATE_CONNECTING:\r
+        //\r
+        //  Validate the local address\r
+        //\r
+        switch ( pSockAddr->sa_family ) {\r
+        default:\r
+          DEBUG (( DEBUG_CONNECT,\r
+                    "ERROR - Invalid bind address family: %d\r\n",\r
+                    pSockAddr->sa_family ));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+\r
+        case AF_INET:\r
+          //\r
+          //  Determine the connection point within the network stack\r
+          //\r
+          switch ( pSocket->Type ) {\r
+          default:\r
+            DEBUG (( DEBUG_CONNECT,\r
+                      "ERROR - Invalid socket type: %d\r\n",\r
+                      pSocket->Type));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\r
+\r
+          case SOCK_STREAM:\r
+          case SOCK_SEQPACKET:\r
+            //\r
+            //  Determine if the connection processing is completed\r
+            //\r
+            Status = EslTcpConnectPoll4 ( pSocket );\r
+\r
+            //\r
+            //  Set the next state if connected\r
+            //\r
+            if ( EFI_NOT_READY != Status ) {\r
+              if ( !EFI_ERROR ( Status )) {\r
+                pSocket->State = SOCKET_STATE_CONNECTED;\r
+              }\r
+              else {\r
+                pSocket->State = SOCKET_STATE_BOUND;\r
+              }\r
+            }\r
+            break;\r
+\r
+          case SOCK_DGRAM:\r
+            //\r
+            //  Already connected\r
+            //\r
+            pSocket->errno = EISCONN;\r
+            Status = EFI_ALREADY_STARTED;\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+        break;\r
+\r
+      case SOCKET_STATE_CONNECTED:\r
+        //\r
+        //  Already connected\r
+        //\r
+        pSocket->errno = EISCONN;\r
+        Status = EFI_ALREADY_STARTED;\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Release the socket layer synchronization\r
+      //\r
+      RESTORE_TPL ( TplPrevious );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      //\r
+      //  Bad socket protocol\r
+      //\r
+      DEBUG (( DEBUG_ERROR | DEBUG_CONNECT,\r
+                "ERROR - pSocketProtocol invalid!\r\n" ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DEBUG (( DEBUG_CONNECT, "Exiting SocketConnect, Status: %r\r\n", Status ));\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Creates a child handle and installs a protocol.\r
+  \r
+  The CreateChild() function installs a protocol on ChildHandle. \r
+  If pChildHandle is a pointer to NULL, then a new handle is created and returned in pChildHandle. \r
+  If pChildHandle is not a pointer to NULL, then the protocol installs on the existing pChildHandle.\r
+\r
+  @param [in] pThis        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+  @param [in] pChildHandle Pointer to the handle of the child to create. If it is NULL,\r
+                           then a new handle is created. If it is a pointer to an existing UEFI handle, \r
+                           then the protocol is added to the existing UEFI handle.\r
+\r
+  @retval EFI_SUCCESS           The protocol was added to ChildHandle.\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources availabe to create\r
+                                the child\r
+  @retval other                 The child handle was not created\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslSocketCreateChild (\r
+  IN     EFI_SERVICE_BINDING_PROTOCOL * pThis,\r
+  IN OUT EFI_HANDLE * pChildHandle\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Create a socket structure\r
+  //\r
+  Status = EslSocketAllocate ( pChildHandle,\r
+                               DEBUG_SOCKET,\r
+                               &pSocket );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Destroys a child handle with a protocol installed on it.\r
+  \r
+  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol \r
+  that was installed by CreateChild() from ChildHandle. If the removed protocol is the \r
+  last protocol on ChildHandle, then ChildHandle is destroyed.\r
+\r
+  @param [in] pThis       Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+  @param [in] ChildHandle Handle of the child to destroy\r
+\r
+  @retval EFI_SUCCESS           The protocol was removed from ChildHandle.\r
+  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.\r
+  @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.\r
+  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle\r
+                                because its services are being used.\r
+  @retval other                 The child handle was not destroyed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslSocketDestroyChild (\r
+  IN EFI_SERVICE_BINDING_PROTOCOL * pThis,\r
+  IN EFI_HANDLE ChildHandle\r
+  )\r
+{\r
+  DT_LAYER * pLayer;\r
+  DT_SOCKET * pSocket;\r
+  DT_SOCKET * pSocketPrevious;\r
+  EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Locate the socket control structure\r
+  //\r
+  pLayer = &mEslLayer;\r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiSocketProtocolGuid,\r
+                  (VOID **)&pSocketProtocol,\r
+                  pLayer->ImageHandle,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Synchronize with the socket layer\r
+    //\r
+    RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+    //\r
+    //  Walk the socket list\r
+    //\r
+    pSocketPrevious = pLayer->pSocketList;\r
+    if ( NULL != pSocketPrevious ) {\r
+      if ( pSocket == pSocketPrevious ) {\r
+        //\r
+        //  Remove the socket from the head of the list\r
+        //\r
+        pLayer->pSocketList = pSocket->pNext;\r
+      }\r
+      else {\r
+        //\r
+        //  Find the socket in the middle of the list\r
+        //\r
+        while (( NULL != pSocketPrevious )\r
+          && ( pSocket != pSocketPrevious->pNext )) {\r
+          //\r
+          //  Set the next socket\r
+          //\r
+          pSocketPrevious = pSocketPrevious->pNext;\r
+        }\r
+        if ( NULL != pSocketPrevious ) {\r
+          //\r
+          //  Remove the socket from the middle of the list\r
+          //\r
+          pSocketPrevious = pSocket->pNext;\r
+        }\r
+      }\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DEBUG_POOL,\r
+                "ERROR - Socket list is empty!\r\n" ));\r
+    }\r
+\r
+    //\r
+    //  Release the socket layer synchronization\r
+    //\r
+    RESTORE_TPL ( TplPrevious );\r
+\r
+    //\r
+    //  Determine if the socket was found\r
+    //\r
+    if ( NULL != pSocketPrevious ) {\r
+      pSocket->pNext = NULL;\r
+\r
+      //\r
+      //  Remove the socket protocol\r
+      //\r
+      Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                ChildHandle,\r
+                &gEfiSocketProtocolGuid,\r
+                &pSocket->SocketProtocol,\r
+                NULL );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_POOL | DEBUG_INFO,\r
+                    "Removed:   gEfiSocketProtocolGuid from 0x%08x\r\n",\r
+                    ChildHandle ));\r
+\r
+        //\r
+        //  Free the socket structure\r
+        //\r
+        Status = gBS->FreePool ( pSocket );\r
+        if ( !EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_POOL,\r
+                    "0x%08x: Free pSocket, %d bytes\r\n",\r
+                    pSocket,\r
+                    sizeof ( *pSocket )));\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_ERROR | DEBUG_POOL,\r
+                    "ERROR - Failed to free pSocket 0x%08x, Status: %r\r\n",\r
+                    pSocket,\r
+                    Status ));\r
+        }\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INFO,\r
+                    "ERROR - Failed to remove gEfiSocketProtocolGuid from 0x%08x, Status: %r\r\n",\r
+                    ChildHandle,\r
+                    Status ));\r
+      }\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DEBUG_INFO,\r
+                "ERROR - The socket was not in the socket list!\r\n" ));\r
+      Status = EFI_NOT_FOUND;\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_ERROR,\r
+              "ERROR - Failed to open socket protocol on 0x%08x, Status; %r\r\n",\r
+              ChildHandle,\r
+              Status ));\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Get the local address.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [out] pAddress       Network address to receive the local system address\r
+\r
+  @param [in,out] pAddressLength  Length of the local network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Local address successfully returned\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketGetLocalAddress (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+  \r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  \r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Verify the address buffer and length address\r
+    //\r
+    if (( NULL != pAddress ) && ( NULL != pAddressLength )) {\r
+      //\r
+      //  Verify the socket state\r
+      //\r
+      if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
+        //\r
+        //  Synchronize with the socket layer\r
+        //\r
+        RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+        //\r
+        //  Validate the local address\r
+        //\r
+        switch ( pSocket->Domain ) {\r
+        default:\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - Invalid socket address family: %d\r\n",\r
+                    pSocket->Domain ));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+\r
+        case AF_INET:\r
+          //\r
+          //  Determine the connection point within the network stack\r
+          //\r
+          switch ( pSocket->Type ) {\r
+          default:\r
+            DEBUG (( DEBUG_RX,\r
+                      "ERROR - Invalid socket type: %d\r\n",\r
+                      pSocket->Type));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            break;\r
+\r
+          case SOCK_STREAM:\r
+          case SOCK_SEQPACKET:\r
+            //\r
+            //  Get the local address\r
+            //\r
+            Status = EslTcpGetLocalAddress4 ( pSocket,\r
+                                              pAddress,\r
+                                              pAddressLength );\r
+            break;\r
+\r
+          case SOCK_DGRAM:\r
+            //\r
+            //  Get the local address\r
+            //\r
+            Status = EslUdpGetLocalAddress4 ( pSocket,\r
+                                              pAddress,\r
+                                              pAddressLength );\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+\r
+        //\r
+        //  Release the socket layer synchronization\r
+        //\r
+        RESTORE_TPL ( TplPrevious );\r
+      }\r
+      else {\r
+        pSocket->errno = ENOTCONN;\r
+        Status = EFI_NOT_STARTED;\r
+      }\r
+    }\r
+    else {\r
+      pSocket->errno = EINVAL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  \r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Get the peer address.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Remote address successfully returned\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketGetPeerAddress (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+  \r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  \r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Verify the address buffer and length address\r
+    //\r
+    if (( NULL != pAddress ) && ( NULL != pAddressLength )) {\r
+      //\r
+      //  Verify the socket state\r
+      //\r
+      if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
+        //\r
+        //  Synchronize with the socket layer\r
+        //\r
+        RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+        //\r
+        //  Validate the local address\r
+        //\r
+        switch ( pSocket->Domain ) {\r
+        default:\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - Invalid socket address family: %d\r\n",\r
+                    pSocket->Domain ));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+\r
+        case AF_INET:\r
+          //\r
+          //  Determine the connection point within the network stack\r
+          //\r
+          switch ( pSocket->Type ) {\r
+          default:\r
+            DEBUG (( DEBUG_RX,\r
+                      "ERROR - Invalid socket type: %d\r\n",\r
+                      pSocket->Type));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            break;\r
+\r
+          case SOCK_STREAM:\r
+          case SOCK_SEQPACKET:\r
+            //\r
+            //  Verify the port state\r
+            //\r
+            Status = EslTcpGetRemoteAddress4 ( pSocket,\r
+                                               pAddress,\r
+                                               pAddressLength );\r
+            break;\r
+\r
+          case SOCK_DGRAM:\r
+            //\r
+            //  Verify the port state\r
+            //\r
+            Status = EslUdpGetRemoteAddress4 ( pSocket,\r
+                                               pAddress,\r
+                                               pAddressLength );\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+\r
+        //\r
+        //  Release the socket layer synchronization\r
+        //\r
+        RESTORE_TPL ( TplPrevious );\r
+      }\r
+      else {\r
+        pSocket->errno = ENOTCONN;\r
+        Status = EFI_NOT_STARTED;\r
+      }\r
+    }\r
+    else {\r
+      pSocket->errno = EINVAL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  \r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Establish the known port to listen for network connections.\r
+\r
+  The ::SocketListen routine places the port into a state that enables connection\r
+  attempts.  Connections are placed into FIFO order in a queue to be serviced\r
+  by the application.  The application calls the ::SocketAccept routine to remove\r
+  the next connection from the queue and get the associated socket.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html">POSIX</a>\r
+  documentation for the listen routine is available online for reference.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] Backlog         Backlog specifies the maximum FIFO depth for\r
+                              the connections waiting for the application\r
+                              to call accept.  Connection attempts received\r
+                              while the queue is full are refused.\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+  @retval Other - Failed to enable the socket for listen\r
+\r
+**/\r
+EFI_STATUS\r
+EslSocketListen (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN INT32 Backlog,\r
+  OUT int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_STATUS TempStatus;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Assume success\r
+    //\r
+    pSocket->Status = EFI_SUCCESS;\r
+    pSocket->errno = 0;\r
+\r
+    //\r
+    //  Verify that the bind operation was successful\r
+    //\r
+    if ( SOCKET_STATE_BOUND == pSocket->State ) {\r
+      //\r
+      //  Synchronize with the socket layer\r
+      //\r
+      RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+      //\r
+      //  Create the event for SocketAccept completion\r
+      //\r
+      Status = gBS->CreateEvent ( 0,\r
+                                  TplPrevious,\r
+                                  NULL,\r
+                                  NULL,\r
+                                  &pSocket->WaitAccept );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_POOL,\r
+                  "0x%08x: Created WaitAccept event\r\n",\r
+                  pSocket->WaitAccept ));\r
+        //\r
+        //  Set the maximum FIFO depth\r
+        //\r
+        if ( 0 >= Backlog ) {\r
+          Backlog = MAX_PENDING_CONNECTIONS;\r
+        }\r
+        else {\r
+          if ( SOMAXCONN < Backlog ) {\r
+            Backlog = SOMAXCONN;\r
+          }\r
+          else {\r
+            pSocket->MaxFifoDepth = Backlog;\r
+          }\r
+        }\r
+\r
+        //\r
+        //  Validate the local address\r
+        //\r
+        switch ( pSocket->Domain ) {\r
+        default:\r
+          DEBUG (( DEBUG_BIND,\r
+                    "ERROR - Invalid socket address family: %d\r\n",\r
+                    pSocket->Domain ));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+\r
+        case AF_INET:\r
+          //\r
+          //  Determine the connection point within the network stack\r
+          //\r
+          switch ( pSocket->Type ) {\r
+          default:\r
+            DEBUG (( DEBUG_BIND,\r
+                      "ERROR - Invalid socket type: %d\r\n",\r
+                      pSocket->Type));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\r
+\r
+          case SOCK_STREAM:\r
+          case SOCK_SEQPACKET:\r
+            Status = EslTcpListen4 ( pSocket );\r
+            break;\r
+\r
+/*\r
+          case SOCK_DGRAM:\r
+            Status = UdpListen4 ( pSocket );\r
+            break;\r
+*/\r
+          }\r
+          break;\r
+        }\r
+\r
+        //\r
+        //  Place the socket in the listen state if successful\r
+        //\r
+        if ( !EFI_ERROR ( Status )) {\r
+          pSocket->State = SOCKET_STATE_LISTENING;\r
+        }\r
+        else {\r
+          //\r
+          //  Not waiting for SocketAccept to complete\r
+          //\r
+          TempStatus = gBS->CloseEvent ( pSocket->WaitAccept );\r
+          if ( !EFI_ERROR ( TempStatus )) {\r
+            DEBUG (( DEBUG_POOL,\r
+                      "0x%08x: Closed WaitAccept event\r\n",\r
+                      pSocket->WaitAccept ));\r
+            pSocket->WaitAccept = NULL;\r
+          }\r
+          else {\r
+            DEBUG (( DEBUG_ERROR | DEBUG_POOL,\r
+                      "ERROR - Failed to close WaitAccept event, Status: %r\r\n",\r
+                      TempStatus ));\r
+            ASSERT ( EFI_SUCCESS == TempStatus );\r
+          }\r
+        }\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_ERROR | DEBUG_LISTEN,\r
+                  "ERROR - Failed to create the WaitAccept event, Status: %r\r\n",\r
+                  Status ));\r
+        pSocket->errno = ENOMEM;\r
+      }\r
+\r
+      //\r
+      //  Release the socket layer synchronization\r
+      //\r
+      RESTORE_TPL ( TplPrevious );\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DEBUG_LISTEN,\r
+                "ERROR - Bind operation must be performed first!\r\n" ));\r
+      pSocket->errno = EDESTADDRREQ;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Get the socket options\r
+\r
+  Retrieve the socket options one at a time by name.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] pSocketProtocol   Address of the socket protocol structure.\r
+  @param [in] level             Option protocol level\r
+  @param [in] OptionName        Name of the option\r
+  @param [out] pOptionValue     Buffer to receive the option value\r
+  @param [in,out] pOptionLength Length of the buffer in bytes,\r
+                                upon return length of the option value in bytes\r
+  @param [out] pErrno           Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketOptionGet (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int level,\r
+  IN int OptionName,\r
+  OUT void * __restrict pOptionValue,\r
+  IN OUT socklen_t * __restrict pOptionLength,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  int errno;\r
+  socklen_t LengthInBytes;\r
+  socklen_t MaxBytes;\r
+  UINT8 * pOptionData;\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  errno = EINVAL;\r
+  Status = EFI_INVALID_PARAMETER;\r
+\r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if (( NULL != pSocketProtocol )\r
+    && ( NULL != pOptionValue )\r
+    && ( NULL != pOptionLength )) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+    LengthInBytes = 0;\r
+    MaxBytes = *pOptionLength;\r
+    pOptionData = NULL;\r
+    switch ( level ) {\r
+    default:\r
+      //\r
+      //  Protocol level not supported\r
+      //\r
+      errno = ENOTSUP;\r
+      Status = EFI_UNSUPPORTED;\r
+      break;\r
+\r
+    case SOL_SOCKET:\r
+      switch ( OptionName ) {\r
+      default:\r
+        //\r
+        //  Option not supported\r
+        //\r
+        errno = ENOTSUP;\r
+        Status = EFI_UNSUPPORTED;\r
+        break;\r
+\r
+      case SO_RCVTIMEO:\r
+        //\r
+        //  Return the receive timeout\r
+        //\r
+        pOptionData = (UINT8 *)&pSocket->RxTimeout;\r
+        LengthInBytes = sizeof ( pSocket->RxTimeout );\r
+        break;\r
+        \r
+      case SO_RCVBUF:\r
+        //\r
+        //  Return the maximum transmit buffer size\r
+        //\r
+        pOptionData = (UINT8 *)&pSocket->MaxRxBuf;\r
+        LengthInBytes = sizeof ( pSocket->MaxRxBuf );\r
+        break;\r
+\r
+      case SO_SNDBUF:\r
+        //\r
+        //  Return the maximum transmit buffer size\r
+        //\r
+        pOptionData = (UINT8 *)&pSocket->MaxTxBuf;\r
+        LengthInBytes = sizeof ( pSocket->MaxTxBuf );\r
+        break;\r
+\r
+      case SO_TYPE:\r
+        //\r
+        //  Return the socket type\r
+        //\r
+        pOptionData = (UINT8 *)&pSocket->Type;\r
+        LengthInBytes = sizeof ( pSocket->Type );\r
+        break;\r
+      }\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Return the option length\r
+    //\r
+    *pOptionLength = LengthInBytes;\r
+\r
+    //\r
+    //  Return the option value\r
+    //\r
+    if ( NULL != pOptionData ) {\r
+      //\r
+      //  Silently truncate the value length\r
+      //\r
+      if ( LengthInBytes > MaxBytes ) {\r
+        LengthInBytes = MaxBytes;\r
+      }\r
+      CopyMem ( pOptionValue, pOptionData, LengthInBytes );\r
+      errno = 0;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    *pErrno = errno;\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Set the socket options\r
+\r
+  Adjust the socket options one at a time by name.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [in] level           Option protocol level\r
+  @param [in] OptionName      Name of the option\r
+  @param [in] pOptionValue    Buffer containing the option value\r
+  @param [in] OptionLength    Length of the buffer in bytes\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketOptionSet (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int level,\r
+  IN int OptionName,\r
+  IN CONST void * pOptionValue,\r
+  IN socklen_t OptionLength,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  int errno;\r
+  socklen_t LengthInBytes;\r
+  UINT8 * pOptionData;\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  \r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Assume failure\r
+  //\r
+  errno = EINVAL;\r
+  Status = EFI_INVALID_PARAMETER;\r
+  \r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if (( NULL != pSocketProtocol )\r
+    && ( NULL != pOptionValue )) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+    LengthInBytes = 0;\r
+    pOptionData = NULL;\r
+    switch ( level ) {\r
+    default:\r
+      //\r
+      //  Protocol level not supported\r
+      //\r
+      errno = ENOTSUP;\r
+      Status = EFI_UNSUPPORTED;\r
+      break;\r
+  \r
+    case SOL_SOCKET:\r
+      switch ( OptionName ) {\r
+      default:\r
+        //\r
+        //  Option not supported\r
+        //\r
+        errno = ENOTSUP;\r
+        Status = EFI_UNSUPPORTED;\r
+        break;\r
+  \r
+      case SO_RCVTIMEO:\r
+        //\r
+        //  Return the receive timeout\r
+        //\r
+        pOptionData = (UINT8 *)&pSocket->RxTimeout;\r
+        LengthInBytes = sizeof ( pSocket->RxTimeout );\r
+        break;\r
+\r
+      case SO_RCVBUF:\r
+        //\r
+        //  Return the maximum transmit buffer size\r
+        //\r
+        pOptionData = (UINT8 *)&pSocket->MaxRxBuf;\r
+        LengthInBytes = sizeof ( pSocket->MaxRxBuf );\r
+        break;\r
+\r
+      case SO_SNDBUF:\r
+        //\r
+        //  Send buffer size\r
+        //\r
+        //\r
+        //  Return the maximum transmit buffer size\r
+        //\r
+        pOptionData = (UINT8 *)&pSocket->MaxTxBuf;\r
+        LengthInBytes = sizeof ( pSocket->MaxTxBuf );\r
+        break;\r
+      }\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Validate the option length\r
+    //\r
+    if ( LengthInBytes <= OptionLength ) {\r
+      //\r
+      //  Set the option value\r
+      //\r
+      if ( NULL != pOptionData ) {\r
+        CopyMem ( pOptionData, pOptionValue, LengthInBytes );\r
+        errno = 0;\r
+        Status = EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+  \r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    *pErrno = errno;\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Allocate a packet for a receive or transmit operation\r
+\r
+  @param [in] ppPacket      Address to receive the DT_PACKET structure\r
+  @param [in] LengthInBytes Length of the packet structure\r
+  @param [in] DebugFlags    Flags for debug messages\r
+\r
+  @retval EFI_SUCCESS - The packet was allocated successfully\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketPacketAllocate (\r
+  IN DT_PACKET ** ppPacket,\r
+  IN size_t LengthInBytes,\r
+  IN UINTN DebugFlags\r
+  )\r
+{\r
+  DT_PACKET * pPacket;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Allocate a packet structure\r
+  //\r
+  LengthInBytes += sizeof ( *pPacket )\r
+                - sizeof ( pPacket->Op );\r
+  Status = gBS->AllocatePool ( EfiRuntimeServicesData,\r
+                               LengthInBytes,\r
+                               (VOID **)&pPacket );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+              "0x%08x: Allocate pPacket, %d bytes\r\n",\r
+              pPacket,\r
+              LengthInBytes ));\r
+    pPacket->PacketSize = LengthInBytes;\r
+  }\r
+  else {\r
+    DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INFO,\r
+              "ERROR - Packet allocation failed for %d bytes, Status: %r\r\n",\r
+              LengthInBytes,\r
+              Status ));\r
+    pPacket = NULL;\r
+  }\r
+\r
+  //\r
+  //  Return the packet\r
+  //\r
+  *ppPacket = pPacket;\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Free a packet used for receive or transmit operation\r
+\r
+  @param [in] pPacket     Address of the DT_PACKET structure\r
+  @param [in] DebugFlags  Flags for debug messages\r
+\r
+  @retval EFI_SUCCESS - The packet was allocated successfully\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketPacketFree (\r
+  IN DT_PACKET * pPacket,\r
+  IN UINTN DebugFlags\r
+  )\r
+{\r
+  UINTN LengthInBytes;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Allocate a packet structure\r
+  //\r
+  LengthInBytes = pPacket->PacketSize;\r
+  Status = gBS->FreePool ( pPacket );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    DEBUG (( DebugFlags | DEBUG_POOL,\r
+              "0x%08x: Free pPacket, %d bytes\r\n",\r
+              pPacket,\r
+              LengthInBytes ));\r
+  }\r
+  else {\r
+    DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INFO,\r
+              "ERROR - Failed to free packet 0x%08x, Status: %r\r\n",\r
+              pPacket,\r
+              Status ));\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Poll a socket for pending activity.\r
+\r
+  The SocketPoll routine checks a socket for pending activity associated\r
+  with the event mask.  Activity is returned in the detected event buffer.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] Events    Events of interest for this socket\r
+\r
+  @param [in] pEvents   Address to receive the detected events\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully polled\r
+  @retval EFI_INVALID_PARAMETER - When pEvents is NULL\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketPoll (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN short Events,\r
+  IN short * pEvents,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  short DetectedEvents;\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+  short ValidEvents;\r
+\r
+  DEBUG (( DEBUG_POLL, "Entering SocketPoll\r\n" ));\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  DetectedEvents = 0;\r
+  pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+  pSocket->errno = 0;\r
+\r
+  //\r
+  //  Verify the socket state\r
+  //\r
+  if ( !pSocket->bConfigured ) {\r
+    //\r
+    //  Synchronize with the socket layer\r
+    //\r
+    RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+    //\r
+    //  Validate the local address\r
+    //\r
+    switch ( pSocket->Domain ) {\r
+    default:\r
+      DEBUG (( DEBUG_RX,\r
+                "ERROR - Invalid socket address family: %d\r\n",\r
+                pSocket->Domain ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      pSocket->errno = EADDRNOTAVAIL;\r
+      break;\r
+\r
+    case AF_INET:\r
+      //\r
+      //  Determine the connection point within the network stack\r
+      //\r
+      switch ( pSocket->Type ) {\r
+      default:\r
+        DEBUG (( DEBUG_RX,\r
+                  "ERROR - Invalid socket type: %d\r\n",\r
+                  pSocket->Type));\r
+        Status = EFI_INVALID_PARAMETER;\r
+        pSocket->errno = EADDRNOTAVAIL;\r
+        break;\r
+\r
+      case SOCK_STREAM:\r
+      case SOCK_SEQPACKET:\r
+        //\r
+        //  Verify the port state\r
+        //\r
+        Status = EslTcpSocketIsConfigured4 ( pSocket );\r
+        break;\r
+\r
+      case SOCK_DGRAM:\r
+        //\r
+        //  Verify the port state\r
+        //\r
+        Status = EslUdpSocketIsConfigured4 ( pSocket );\r
+        break;\r
+      }\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Release the socket layer synchronization\r
+    //\r
+    RESTORE_TPL ( TplPrevious );\r
+  }\r
+  if ( !EFI_ERROR ( Status )) {\r
+    //\r
+    //  Check for invalid events\r
+    //\r
+    ValidEvents = POLLIN\r
+                | POLLPRI\r
+                | POLLOUT | POLLWRNORM\r
+                | POLLERR\r
+                | POLLHUP\r
+                | POLLNVAL\r
+                | POLLRDNORM\r
+                | POLLRDBAND\r
+                | POLLWRBAND ;\r
+    if ( 0 != ( Events & ( ~ValidEvents ))) {\r
+      DetectedEvents |= POLLNVAL;\r
+      DEBUG (( DEBUG_INFO | DEBUG_POLL,\r
+                "ERROR - Invalid event mask, Valid Events: 0x%04x, Invalid Events: 0x%04x\r\n",\r
+                Events & ValidEvents,\r
+                Events & ( ~ValidEvents )));\r
+    }\r
+    else {\r
+      //\r
+      //  Check for pending connections\r
+      //\r
+      if ( 0 != pSocket->FifoDepth ) {\r
+        //\r
+        //  A connection is waiting for an accept call\r
+        //  See posix connect documentation at\r
+        //  http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.htm\r
+        //\r
+        DetectedEvents |= POLLIN | POLLRDNORM;\r
+      }\r
+      if ( pSocket->bConnected ) {\r
+        //\r
+        //  A connection is present\r
+        //  See posix connect documentation at\r
+        //  http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.htm\r
+        //\r
+        DetectedEvents |= POLLOUT | POLLWRNORM;\r
+      }\r
+\r
+      //\r
+      //  The following bits are set based upon the POSIX poll documentation at\r
+      //  http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html\r
+      //\r
+\r
+      //\r
+      //  Check for urgent receive data\r
+      //\r
+      if ( 0 < pSocket->RxOobBytes ) {\r
+        DetectedEvents |= POLLRDBAND | POLLPRI | POLLIN;\r
+      }\r
+\r
+      //\r
+      //  Check for normal receive data\r
+      //\r
+      if (( 0 < pSocket->RxBytes )\r
+        || ( EFI_SUCCESS != pSocket->RxError )) {\r
+        DetectedEvents |= POLLRDNORM | POLLIN;\r
+      }\r
+\r
+      //\r
+      //  Handle the receive errors\r
+      //\r
+      if (( EFI_SUCCESS != pSocket->RxError )\r
+        && ( 0 == ( DetectedEvents & POLLIN ))) {\r
+        DetectedEvents |= POLLERR | POLLIN | POLLRDNORM | POLLRDBAND;\r
+      }\r
+\r
+      //\r
+      //  Check for urgent transmit data buffer space\r
+      //\r
+      if (( MAX_TX_DATA > pSocket->TxOobBytes )\r
+        || ( EFI_SUCCESS != pSocket->TxError )) {\r
+        DetectedEvents |= POLLWRBAND;\r
+      }\r
+\r
+      //\r
+      //  Check for normal transmit data buffer space\r
+      //\r
+      if (( MAX_TX_DATA > pSocket->TxBytes )\r
+        || ( EFI_SUCCESS != pSocket->TxError )) {\r
+        DetectedEvents |= POLLWRNORM;\r
+      }\r
+\r
+      //\r
+      //  Handle the transmit error\r
+      //\r
+      if ( EFI_ERROR ( pSocket->TxError )) {\r
+        DetectedEvents |= POLLERR;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the detected events\r
+  //\r
+  *pEvents = DetectedEvents & ( Events\r
+                              | POLLERR\r
+                              | POLLHUP\r
+                              | POLLNVAL );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DEBUG (( DEBUG_POLL, "Exiting SocketPoll, Status: %r\r\n", Status ));\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Receive data from a network connection.\r
+\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [in] Flags           Message control flags\r
+  \r
+  @param [in] BufferLength    Length of the the buffer\r
+  \r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+  \r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketReceive (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN INT32 Flags,\r
+  IN size_t BufferLength,\r
+  IN UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Verify the socket state\r
+    //\r
+    if ( !pSocket->bConfigured ) {\r
+      //\r
+      //  Synchronize with the socket layer\r
+      //\r
+      RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+      //\r
+      //  Validate the local address\r
+      //\r
+      switch ( pSocket->Domain ) {\r
+      default:\r
+        DEBUG (( DEBUG_RX,\r
+                  "ERROR - Invalid socket address family: %d\r\n",\r
+                  pSocket->Domain ));\r
+        Status = EFI_INVALID_PARAMETER;\r
+        pSocket->errno = EADDRNOTAVAIL;\r
+        break;\r
+\r
+      case AF_INET:\r
+        //\r
+        //  Determine the connection point within the network stack\r
+        //\r
+        switch ( pSocket->Type ) {\r
+        default:\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - Invalid socket type: %d\r\n",\r
+                    pSocket->Type));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          break;\r
+\r
+        case SOCK_STREAM:\r
+        case SOCK_SEQPACKET:\r
+          //\r
+          //  Verify the port state\r
+          //\r
+          Status = EslTcpSocketIsConfigured4 ( pSocket );\r
+          break;\r
+\r
+        case SOCK_DGRAM:\r
+          //\r
+          //  Verify the port state\r
+          //\r
+          Status = EslUdpSocketIsConfigured4 ( pSocket );\r
+          break;\r
+        }\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Release the socket layer synchronization\r
+      //\r
+      RESTORE_TPL ( TplPrevious );\r
+\r
+      //\r
+      //  Set errno if a failure occurs\r
+      //\r
+      if ( EFI_ERROR ( Status )) {\r
+        pSocket->errno = EADDRNOTAVAIL;\r
+      }\r
+    }\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Validate the buffer length\r
+      //\r
+      if (( NULL == pDataLength )\r
+        && ( 0 > pDataLength )\r
+        && ( NULL == pBuffer )) {\r
+        if ( NULL == pDataLength ) {\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - pDataLength is NULL!\r\n" ));\r
+        }\r
+        else if ( NULL == pBuffer ) {\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - pBuffer is NULL!\r\n" ));\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - Data length < 0!\r\n" ));\r
+        }\r
+        Status = EFI_INVALID_PARAMETER;\r
+        pSocket->errno = EFAULT;\r
+      }\r
+      else{\r
+        //\r
+        //  Synchronize with the socket layer\r
+        //\r
+        RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+        //\r
+        //  Validate the local address\r
+        //\r
+        switch ( pSocket->Domain ) {\r
+        default:\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - Invalid socket address family: %d\r\n",\r
+                    pSocket->Domain ));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+\r
+        case AF_INET:\r
+          //\r
+          //  Determine the connection point within the network stack\r
+          //\r
+          switch ( pSocket->Type ) {\r
+          default:\r
+            DEBUG (( DEBUG_RX,\r
+                      "ERROR - Invalid socket type: %d\r\n",\r
+                      pSocket->Type));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\r
+\r
+          case SOCK_STREAM:\r
+          case SOCK_SEQPACKET:\r
+            Status = EslTcpReceive4 ( pSocket,\r
+                                      Flags,\r
+                                      BufferLength,\r
+                                      pBuffer,\r
+                                      pDataLength,\r
+                                      pAddress,\r
+                                      pAddressLength );\r
+            break;\r
+\r
+          case SOCK_DGRAM:\r
+            Status = EslUdpReceive4 ( pSocket,\r
+                                      Flags,\r
+                                      BufferLength,\r
+                                      pBuffer,\r
+                                      pDataLength,\r
+                                      pAddress,\r
+                                      pAddressLength);\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+\r
+        //\r
+        //  Release the socket layer synchronization\r
+        //\r
+        RESTORE_TPL ( TplPrevious );\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Shutdown the socket receive and transmit operations\r
+\r
+  The SocketShutdown routine stops the socket receive and transmit\r
+  operations.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [in] How             Which operations to stop\r
+  \r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket operations successfully shutdown\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketShutdown (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int How,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+  \r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Verify that the socket is connected\r
+    //\r
+    if ( pSocket->bConnected ) {\r
+      //\r
+      //  Validate the How value\r
+      //\r
+      if (( SHUT_RD <= How ) && ( SHUT_RDWR >= How )) {\r
+        //\r
+        //  Synchronize with the socket layer\r
+        //\r
+        RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+        //\r
+        //  Disable the receiver if requested\r
+        //\r
+        if (( SHUT_RD == How ) || ( SHUT_RDWR == How )) {\r
+          pSocket->bRxDisable = TRUE;\r
+        }\r
+\r
+        //\r
+        //  Disable the transmitter if requested\r
+        //\r
+        if (( SHUT_WR == How ) || ( SHUT_RDWR == How )) {\r
+          pSocket->bTxDisable = TRUE;\r
+        }\r
+\r
+        //\r
+        //  Validate the local address\r
+        //\r
+        switch ( pSocket->Domain ) {\r
+        default:\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - Invalid socket address family: %d\r\n",\r
+                    pSocket->Domain ));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+        \r
+        case AF_INET:\r
+          //\r
+          //  Determine the connection point within the network stack\r
+          //\r
+          switch ( pSocket->Type ) {\r
+          default:\r
+            DEBUG (( DEBUG_RX,\r
+                      "ERROR - Invalid socket type: %d\r\n",\r
+                      pSocket->Type));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            break;\r
+        \r
+          case SOCK_STREAM:\r
+          case SOCK_SEQPACKET:\r
+            //\r
+            //  Cancel the pending receive operation\r
+            //\r
+            Status = EslTcpRxCancel4 ( pSocket );\r
+            break;\r
+        \r
+          case SOCK_DGRAM:\r
+            //\r
+            //  Cancel the pending receive operation\r
+            //\r
+            Status = EslUdpRxCancel4 ( pSocket );\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+        \r
+        //\r
+        //  Release the socket layer synchronization\r
+        //\r
+        RESTORE_TPL ( TplPrevious );\r
+      }\r
+      else {\r
+        //\r
+        //  The socket is not connected\r
+        //\r
+        pSocket->errno = ENOTCONN;\r
+        Status = EFI_NOT_STARTED;\r
+      }\r
+    }\r
+    else {\r
+      //\r
+      //  Invalid How value\r
+      //\r
+      pSocket->errno = EINVAL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Send data using a network connection.\r
+\r
+  The SocketTransmit routine queues the data for transmission to the\r
+  remote network connection.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [in] Flags           Message control flags\r
+  \r
+  @param [in] BufferLength    Length of the the buffer\r
+  \r
+  @param [in] pBuffer         Address of a buffer containing the data to send\r
+  \r
+  @param [in] pDataLength     Address to receive the number of data bytes sent\r
+\r
+  @param [in] pAddress        Network address of the remote system address\r
+\r
+  @param [in] AddressLength   Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully queued for transmit\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketTransmit (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int Flags,\r
+  IN size_t BufferLength,\r
+  IN CONST UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  IN const struct sockaddr * pAddress,\r
+  IN socklen_t AddressLength,\r
+  IN int * pErrno\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Validate the socket\r
+  //\r
+  pSocket = NULL;\r
+  if ( NULL != pSocketProtocol ) {\r
+    pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
+\r
+    //\r
+    //  Verify the socket state\r
+    //\r
+    if ( !pSocket->bConfigured ) {\r
+      //\r
+      //  Synchronize with the socket layer\r
+      //\r
+      RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+    \r
+      //\r
+      //  Validate the local address\r
+      //\r
+      switch ( pSocket->Domain ) {\r
+      default:\r
+        DEBUG (( DEBUG_RX,\r
+                  "ERROR - Invalid socket address family: %d\r\n",\r
+                  pSocket->Domain ));\r
+        Status = EFI_INVALID_PARAMETER;\r
+        pSocket->errno = EADDRNOTAVAIL;\r
+        break;\r
+    \r
+      case AF_INET:\r
+        //\r
+        //  Determine the connection point within the network stack\r
+        //\r
+        switch ( pSocket->Type ) {\r
+        default:\r
+          DEBUG (( DEBUG_RX,\r
+                    "ERROR - Invalid socket type: %d\r\n",\r
+                    pSocket->Type));\r
+          Status = EFI_INVALID_PARAMETER;\r
+          break;\r
+    \r
+        case SOCK_STREAM:\r
+        case SOCK_SEQPACKET:\r
+          //\r
+          //  Verify the port state\r
+          //\r
+          Status = EslTcpSocketIsConfigured4 ( pSocket );\r
+          break;\r
+    \r
+        case SOCK_DGRAM:\r
+          //\r
+          //  Verify the port state\r
+          //\r
+          Status = EslUdpSocketIsConfigured4 ( pSocket );\r
+          break;\r
+        }\r
+        break;\r
+      }\r
+    \r
+      //\r
+      //  Release the socket layer synchronization\r
+      //\r
+      RESTORE_TPL ( TplPrevious );\r
+    \r
+      //\r
+      //  Set errno if a failure occurs\r
+      //\r
+      if ( EFI_ERROR ( Status )) {\r
+        pSocket->errno = EADDRNOTAVAIL;\r
+      }\r
+    }\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Verify that transmit is still allowed\r
+      //\r
+      if ( !pSocket->bTxDisable ) {\r
+        //\r
+        //  Validate the buffer length\r
+        //\r
+        if (( NULL == pDataLength )\r
+          && ( 0 > pDataLength )\r
+          && ( NULL == pBuffer )) {\r
+          if ( NULL == pDataLength ) {\r
+            DEBUG (( DEBUG_RX,\r
+                      "ERROR - pDataLength is NULL!\r\n" ));\r
+          }\r
+          else if ( NULL == pBuffer ) {\r
+            DEBUG (( DEBUG_RX,\r
+                      "ERROR - pBuffer is NULL!\r\n" ));\r
+          }\r
+          else {\r
+            DEBUG (( DEBUG_RX,\r
+                      "ERROR - Data length < 0!\r\n" ));\r
+          }\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EFAULT;\r
+        }\r
+        else {\r
+          //\r
+          //  Validate the remote network address\r
+          //\r
+          if (( NULL != pAddress )\r
+            && ( AddressLength < pAddress->sa_len )) {\r
+            DEBUG (( DEBUG_TX,\r
+                      "ERROR - Invalid sin_len field in address\r\n" ));\r
+            Status = EFI_INVALID_PARAMETER;\r
+            pSocket->errno = EFAULT;\r
+          }\r
+          else {\r
+            //\r
+            //  Synchronize with the socket layer\r
+            //\r
+            RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+            //\r
+            //  Validate the local address\r
+            //\r
+            switch ( pSocket->Domain ) {\r
+            default:\r
+              DEBUG (( DEBUG_RX,\r
+                        "ERROR - Invalid socket address family: %d\r\n",\r
+                        pSocket->Domain ));\r
+              Status = EFI_INVALID_PARAMETER;\r
+              pSocket->errno = EADDRNOTAVAIL;\r
+              break;\r
+\r
+            case AF_INET:\r
+              //\r
+              //  Determine the connection point within the network stack\r
+              //\r
+              switch ( pSocket->Type ) {\r
+              default:\r
+                DEBUG (( DEBUG_RX,\r
+                          "ERROR - Invalid socket type: %d\r\n",\r
+                          pSocket->Type));\r
+                Status = EFI_INVALID_PARAMETER;\r
+                pSocket->errno = EADDRNOTAVAIL;\r
+                break;\r
+\r
+              case SOCK_STREAM:\r
+              case SOCK_SEQPACKET:\r
+                Status = EslTcpTxBuffer4 ( pSocket,\r
+                                           Flags,\r
+                                           BufferLength,\r
+                                           pBuffer,\r
+                                           pDataLength );\r
+                break;\r
+\r
+              case SOCK_DGRAM:\r
+                Status = EslUdpTxBuffer4 ( pSocket,\r
+                                           Flags,\r
+                                           BufferLength,\r
+                                           pBuffer,\r
+                                           pDataLength,\r
+                                           pAddress,\r
+                                           AddressLength );\r
+                break;\r
+              }\r
+              break;\r
+            }\r
+\r
+            //\r
+            //  Release the socket layer synchronization\r
+            //\r
+            RESTORE_TPL ( TplPrevious );\r
+          }\r
+        }\r
+      }\r
+      else {\r
+        //\r
+        //  The transmitter was shutdown\r
+        //\r
+        pSocket->errno = EPIPE;\r
+        Status = EFI_NOT_STARTED;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  if ( NULL != pErrno ) {\r
+    if ( NULL != pSocket ) {\r
+      *pErrno = pSocket->errno;\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *pErrno = EBADF;\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Socket layer's service binding protocol delcaration.\r
+**/\r
+EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding = {\r
+  EslSocketCreateChild,\r
+  EslSocketDestroyChild\r
+};\r
diff --git a/StdLib/EfiSocketLib/Socket.h b/StdLib/EfiSocketLib/Socket.h
new file mode 100644 (file)
index 0000000..42377eb
--- /dev/null
@@ -0,0 +1,1337 @@
+/** @file\r
+  Definitions for the Socket layer driver.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#ifndef _SOCKET_H_\r
+#define _SOCKET_H_\r
+\r
+#include <Efi/EfiSocketLib.h>\r
+\r
+//------------------------------------------------------------------------------\r
+//  Constants\r
+//------------------------------------------------------------------------------\r
+\r
+#define DEBUG_SOCKET        0x20000000  ///<  Display Socket related messages\r
+#define DEBUG_BIND          0x10000000  ///<  Display bind related messages\r
+#define DEBUG_LISTEN        0x08000000  ///<  Display listen related messages\r
+#define DEBUG_CONNECTION    0x04000000  ///<  Display connection list related messages\r
+#define DEBUG_POLL          0x02000000  ///<  Display poll messages\r
+#define DEBUG_ACCEPT        0x01000000  ///<  Display accept related messages\r
+#define DEBUG_RX            0x00800000  ///<  Display receive messages\r
+#define DEBUG_TX            0x00400000  ///<  Display transmit messages\r
+#define DEBUG_CLOSE         0x00200000  ///<  Display close messages\r
+#define DEBUG_CONNECT       0x00100000  ///<  Display connect messages\r
+\r
+#define MAX_PENDING_CONNECTIONS     1   ///<  Maximum connection FIFO depth\r
+#define MAX_RX_DATA         65536       ///<  Maximum receive data size\r
+#define MAX_TX_DATA         ( MAX_RX_DATA * 2 )\r
+#define RX_PACKET_DATA      16384       ///<  Maximum number of bytes in a RX packet\r
+\r
+#define LAYER_SIGNATURE             SIGNATURE_32('S','k','t','L') ///<  DT_LAYER memory signature\r
+#define SERVICE_SIGNATURE           SIGNATURE_32('S','k','t','S') ///<  DT_SERVICE memory signature\r
+#define SOCKET_SIGNATURE            SIGNATURE_32('S','c','k','t') ///<  DT_SOCKET memory signature\r
+#define PORT_SIGNATURE              SIGNATURE_32('P','o','r','t') ///<  DT_PORT memory signature\r
+\r
+typedef enum\r
+{\r
+  NETWORK_TYPE_UNKNOWN = 0,\r
+  NETWORK_TYPE_RAW,\r
+  NETWORK_TYPE_TCP4,\r
+  NETWORK_TYPE_TCP6,\r
+  NETWORK_TYPE_UDP4,\r
+  NETWORK_TYPE_UDP6\r
+} NETWORK_TYPE;\r
+\r
+typedef enum\r
+{\r
+  SOCKET_STATE_NOT_CONFIGURED = 0,  ///<  socket call was successful\r
+  SOCKET_STATE_BOUND,               ///<  bind call was successful\r
+  SOCKET_STATE_LISTENING,           ///<  listen call was successful\r
+  SOCKET_STATE_NO_PORTS,            ///<  No ports available\r
+  SOCKET_STATE_IN_FIFO,             ///<  Socket on FIFO\r
+  SOCKET_STATE_CONNECTING,          ///<  Connecting to a remote system\r
+  SOCKET_STATE_CONNECTED,           ///<  Accept or connect call was successful\r
+\r
+  //\r
+  //  Close state must be the last in the list\r
+  //\r
+  SOCKET_STATE_CLOSED               ///<  Close call was successful\r
+} SOCKET_STATE;\r
+\r
+typedef enum\r
+{\r
+  PORT_STATE_ALLOCATED = 0, ///<  Port allocated\r
+  PORT_STATE_OPEN,          ///<  Port opened\r
+  PORT_STATE_RX_ERROR,      ///<  Receive error detected\r
+\r
+  //\r
+  //  Close state must be last in the list\r
+  //\r
+  PORT_STATE_CLOSE_STARTED, ///<  Close started on port\r
+  PORT_STATE_CLOSE_TX_DONE, ///<  Transmits shutdown\r
+  PORT_STATE_CLOSE_RX_DONE, ///<  Receives shutdown\r
+  PORT_STATE_CLOSE_DONE     ///<  Port close operation complete\r
+} PORT_STATE;\r
+\r
+//------------------------------------------------------------------------------\r
+//  Data Types\r
+//------------------------------------------------------------------------------\r
+\r
+typedef struct _DT_PACKET DT_PACKET;    ///<  Forward declaration\r
+typedef struct _DT_PORT DT_PORT;        ///<  Forward declaration\r
+typedef struct _DT_SOCKET DT_SOCKET;    ///<  Forward declaration\r
+\r
+typedef struct\r
+{\r
+  EFI_TCP4_RECEIVE_DATA RxData;         ///<  Receive operation description\r
+  size_t ValidBytes;                    ///<  Length of valid data in bytes\r
+  UINT8 * pBuffer;                      ///<  Current data pointer\r
+  UINT8 Buffer [ RX_PACKET_DATA ];      ///<  Data buffer\r
+} DT_TCP4_RX_DATA;\r
+\r
+typedef struct\r
+{\r
+  EFI_TCP4_TRANSMIT_DATA TxData;        ///<  Transmit operation description\r
+  UINT8 Buffer [ 1 ];                   ///<  Data buffer\r
+} DT_TCP4_TX_DATA;\r
+\r
+typedef struct\r
+{\r
+  EFI_UDP4_SESSION_DATA Session;        ///< * Remote network address\r
+  EFI_UDP4_RECEIVE_DATA * pRxData;      ///< * Receive operation description\r
+} DT_UDP4_RX_DATA;\r
+\r
+typedef struct\r
+{\r
+  EFI_UDP4_SESSION_DATA Session;        ///<  Remote network address\r
+  EFI_UDP4_TRANSMIT_DATA TxData;        ///<  Transmit operation description\r
+  UINT8 Buffer [ 1 ];                   ///<  Data buffer\r
+} DT_UDP4_TX_DATA;\r
+\r
+typedef struct _DT_PACKET {\r
+  DT_PACKET * pNext;                    ///<  Next packet in the receive list\r
+  size_t PacketSize;                    ///<  Size of this data structure\r
+  union {\r
+    DT_TCP4_RX_DATA Tcp4Rx;             ///<  Receive operation description\r
+    DT_TCP4_TX_DATA Tcp4Tx;             ///<  Transmit operation description\r
+    DT_UDP4_RX_DATA Udp4Rx;             ///<  Receive operation description\r
+    DT_UDP4_TX_DATA Udp4Tx;             ///<  Transmit operation description\r
+  } Op;\r
+} GCC_DT_PACKET;\r
+\r
+/**\r
+  Service control structure\r
+\r
+  The driver uses this structure to manage the network devices.\r
+**/\r
+typedef struct _DT_SERVICE {\r
+  UINTN Signature;          ///<  Structure identification\r
+\r
+  //\r
+  //  Links\r
+  //\r
+  DT_SERVICE * pNext;       ///<  Next service in the service list\r
+\r
+  //\r
+  //  Service data\r
+  //\r
+  CONST DT_SOCKET_BINDING * pSocketBinding; ///<  Name and shutdown routine\r
+  EFI_HANDLE Controller;    ///<  Controller for the service\r
+  VOID * pInterface;        ///<  Network layer service binding interface\r
+\r
+  //\r
+  //  Network data\r
+  //\r
+  NETWORK_TYPE NetworkType; ///<  Type of network service\r
+  DT_PORT * pPortList;      ///<  List of ports using this service\r
+}GCC_DT_SERVICE;\r
+\r
+/**\r
+  Start the close operation on a TCP4 port.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+  @param [in] bAbort      Set TRUE to abort active transfers\r
+  @param [in] DebugFlags  Flags for debug messages\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+PFN_PORT_CLOSE_START (\r
+  IN DT_PORT * pPort,\r
+  IN BOOLEAN bAbort,\r
+  IN UINTN DebugFlags\r
+  );\r
+\r
+/**\r
+  TCP4 context structure\r
+\r
+  The driver uses this structure to manage the TCP4 connections.\r
+**/\r
+typedef struct {\r
+  //\r
+  //  TCP4 context\r
+  //\r
+  EFI_HANDLE Handle;                ///<  TCP4 port handle\r
+  EFI_TCP4_PROTOCOL * pProtocol;    ///<  TCP4 protocol pointer\r
+  EFI_TCP4_CONFIG_DATA ConfigData;  ///<  TCP4 configuration data\r
+  EFI_TCP4_OPTION Option;           ///<  TCP4 port options\r
+  BOOLEAN bConfigured;              ///<  TRUE if configuration was successful\r
+\r
+  //\r
+  //  Tokens\r
+  //\r
+  EFI_TCP4_LISTEN_TOKEN ListenToken;  ///<  Listen control\r
+  EFI_TCP4_CONNECTION_TOKEN ConnectToken; ///<  Connection control\r
+  EFI_TCP4_CLOSE_TOKEN CloseToken;    ///<  Close control\r
+\r
+  //\r
+  //  Receive data management\r
+  //\r
+  EFI_TCP4_IO_TOKEN RxToken;        ///<  Receive token\r
+  DT_PACKET * pReceivePending;      ///<  Receive operation in progress\r
+\r
+  //\r
+  //  Transmit data management\r
+  //\r
+  EFI_TCP4_IO_TOKEN TxOobToken;     ///<  Urgent data token\r
+  DT_PACKET * pTxOobPacket;         ///<  Urgent data in progress\r
+\r
+  EFI_TCP4_IO_TOKEN TxToken;        ///<  Normal data token\r
+  DT_PACKET * pTxPacket;            ///<  Normal transmit in progress\r
+} DT_TCP4_CONTEXT;\r
+\r
+/**\r
+  UDP4 context structure\r
+\r
+  The driver uses this structure to manage the UDP4 connections.\r
+**/\r
+typedef struct {\r
+  //\r
+  //  UDP4 context\r
+  //\r
+  EFI_HANDLE Handle;                ///<  UDP4 port handle\r
+  EFI_UDP4_PROTOCOL * pProtocol;    ///<  UDP4 protocol pointer\r
+  EFI_UDP4_CONFIG_DATA ConfigData;  ///<  UDP4 configuration data\r
+  BOOLEAN bConfigured;              ///<  TRUE if configuration was successful\r
+\r
+  //\r
+  //  Receive data management\r
+  //\r
+  EFI_UDP4_COMPLETION_TOKEN RxToken;///<  Receive token\r
+  DT_PACKET * pReceivePending;      ///<  Receive operation in progress\r
+\r
+  //\r
+  //  Transmit data management\r
+  //\r
+  EFI_UDP4_COMPLETION_TOKEN TxToken;///<  Transmit token\r
+  DT_PACKET * pTxPacket;            ///<  Transmit in progress\r
+} DT_UDP4_CONTEXT;\r
+\r
+\r
+/**\r
+  Port control structure\r
+\r
+  The driver uses this structure to manager the socket's connection\r
+  with the network driver.\r
+**/\r
+typedef struct _DT_PORT {\r
+  UINTN Signature;              ///<  Structure identification\r
+\r
+  //\r
+  //  List links\r
+  //\r
+  DT_PORT * pLinkService;       ///<  Link in service port list\r
+  DT_PORT * pLinkSocket;        ///<  Link in socket port list\r
+\r
+  //\r
+  //  Structures\r
+  //\r
+  DT_SERVICE * pService;        ///<  Service for this port\r
+  DT_SOCKET * pSocket;          ///<  Socket for this port\r
+//  PFN_CLOSE_PORT pfnClosePort;  ///<  Routine to immediately close the port\r
+  PFN_PORT_CLOSE_START * pfnCloseStart; ///<  Routine to start closing the port\r
+\r
+  //\r
+  //  Protocol specific management data\r
+  //\r
+  PORT_STATE State;             ///<  State of the port\r
+  UINTN DebugFlags;             ///<  Debug flags used to close the port\r
+  BOOLEAN bCloseNow;            ///<  TRUE = Close the port immediately\r
+  \r
+  union {\r
+    DT_TCP4_CONTEXT Tcp4;       ///<  TCPv4 management data\r
+    DT_UDP4_CONTEXT Udp4;       ///<  UDPv4 management data\r
+  } Context;\r
+}GCC_DT_PORT;\r
+\r
+/**\r
+  Socket control structure\r
+\r
+  The driver uses this structure to manage the socket.\r
+**/\r
+typedef struct _DT_SOCKET {\r
+  UINTN Signature;          ///<  Structure identification\r
+\r
+  //\r
+  //  Protocol binding\r
+  //\r
+  EFI_SOCKET_PROTOCOL SocketProtocol; ///<  Socket protocol declaration\r
+\r
+  //\r
+  //  Socket management\r
+  //\r
+  DT_SOCKET * pNext;            ///<  Next socket in the list of sockets\r
+  int errno;                    ///<  Error information for this socket\r
+  EFI_STATUS Status;            ///<  Asyncronous error information for this socket\r
+  SOCKET_STATE State;           ///<  Socket state\r
+\r
+  //\r
+  //  Socket data\r
+  //\r
+  int Domain;                   ///<  Specifies family of protocols\r
+  int Type;                     ///<  Specifies how to make network connection\r
+  int Protocol;                 ///<  Specifies lower layer protocol to use\r
+  BOOLEAN bConfigured;          ///<  Set after the socket is configured\r
+\r
+  BOOLEAN bRxDisable;           ///<  Receive disabled via shutdown\r
+  size_t RxBytes;               ///<  Total Rx bytes\r
+  size_t RxOobBytes;            ///<  Urgent Rx bytes\r
+  EFI_STATUS RxError;           ///<  Error during receive\r
+\r
+  BOOLEAN bTxDisable;           ///<  Transmit disabled via shutdown\r
+  size_t TxBytes;               ///<  Normal Tx bytes\r
+  size_t TxOobBytes;            ///<  Urgent Tx bytes\r
+  EFI_STATUS TxError;           ///<  Error during transmit\r
+\r
+  //\r
+  //  Pending connection data\r
+  //\r
+  BOOLEAN bConnected;           ///<  Set when connected, cleared by poll\r
+  EFI_STATUS ConnectStatus;     ///<  Connection status\r
+  UINTN MaxFifoDepth;           ///<  Maximum FIFO depth\r
+  UINTN FifoDepth;              ///<  Number of sockets in the FIFO\r
+  DT_SOCKET * pFifoHead;        ///<  Head of the FIFO\r
+  DT_SOCKET * pFifoTail;        ///<  Tail of the FIFO\r
+  DT_SOCKET * pNextConnection;  ///<  Link in the FIFO\r
+\r
+  //\r
+  //  Network use\r
+  //\r
+  DT_PORT * pPortList;          ///<  List of ports managed by this socket\r
+  EFI_EVENT WaitAccept;         ///<  Wait for accept completion\r
+\r
+  //\r
+  //  Receive data management\r
+  //\r
+  UINT32 MaxRxBuf;                  ///<  Maximum size of the receive buffer\r
+  struct timeval RxTimeout;         ///<  Receive timeout\r
+  DT_PACKET * pRxFree;              ///<  Free packet list\r
+  DT_PACKET * pRxOobPacketListHead; ///<  Urgent data list head\r
+  DT_PACKET * pRxOobPacketListTail; ///<  Urgent data list tail\r
+  DT_PACKET * pRxPacketListHead;    ///<  Normal data list head\r
+  DT_PACKET * pRxPacketListTail;    ///<  Normal data list tail\r
+\r
+  //\r
+  //  Transmit data management\r
+  //\r
+  UINT32 MaxTxBuf;                  ///<  Maximum size of the transmit buffer\r
+  DT_PACKET * pTxOobPacketListHead; ///<  Urgent data list head\r
+  DT_PACKET * pTxOobPacketListTail; ///<  Urgent data list tail\r
+  DT_PACKET * pTxPacketListHead;    ///<  Normal data list head\r
+  DT_PACKET * pTxPacketListTail;    ///<  Normal data list tail\r
+}GCC_DT_SOCKET;\r
+\r
+#define SOCKET_FROM_PROTOCOL(a)  CR(a, DT_SOCKET, SocketProtocol, SOCKET_SIGNATURE) ///< Locate DT_SOCKET from protocol\r
+\r
+/**\r
+  Socket layer control structure\r
+\r
+  The driver uses this structure to manage the driver.\r
+**/\r
+typedef struct {\r
+  UINTN Signature;              ///<  Structure identification\r
+\r
+  //\r
+  //  Service binding interface\r
+  //\r
+  EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;///<  Driver's binding\r
+\r
+  //\r
+  //  Image data\r
+  //\r
+  EFI_HANDLE ImageHandle;       ///<  Image handle\r
+\r
+  //\r
+  //  Network services\r
+  //\r
+  DT_SERVICE * pTcp4List;       ///<  List of Tcp4 services\r
+  DT_SERVICE * pUdp4List;       ///<  List of Udp4 services\r
+\r
+  //\r
+  //  Socket management\r
+  //\r
+  DT_SOCKET * pSocketList;      ///<  List of sockets\r
+  \r
+  //\r
+  //  TCP4 service\r
+  //\r
+  UINTN TcpCloseMax4;           ///<  Number of entries in the ring buffer\r
+  UINTN TcpCloseIn4;            ///<  Offset into TcpClose4 ring buffer - Close request\r
+  UINTN TcpCloseOut4;           ///<  Offset into TcpClose4 ring buffer - Close operation\r
+  EFI_TCP4_PROTOCOL ** ppTcpClose4; ///<  Ring buffer to close TCP4 ports\r
+} DT_LAYER;\r
+\r
+#define LAYER_FROM_SERVICE(a) CR(a, DT_LAYER, ServiceBinding, LAYER_SIGNATURE) ///< Locate DT_LAYER from service binding\r
+\r
+//------------------------------------------------------------------------------\r
+// Data\r
+//------------------------------------------------------------------------------\r
+\r
+extern DT_LAYER mEslLayer;\r
+\r
+//------------------------------------------------------------------------------\r
+// Socket Support Routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Allocate and initialize a DT_SOCKET structure.\r
+  \r
+  The ::SocketAllocate() function allocates a DT_SOCKET structure\r
+  and installs a protocol on ChildHandle.  If pChildHandle is a\r
+  pointer to NULL, then a new handle is created and returned in\r
+  pChildHandle.  If pChildHandle is not a pointer to NULL, then\r
+  the protocol installs on the existing pChildHandle.\r
+\r
+  @param [in, out] pChildHandle Pointer to the handle of the child to create.\r
+                                If it is NULL, then a new handle is created.\r
+                                If it is a pointer to an existing UEFI handle, \r
+                                then the protocol is added to the existing UEFI\r
+                                handle.\r
+  @param [in] DebugFlags        Flags for debug messages\r
+  @param [in, out] ppSocket     The buffer to receive the DT_SOCKET structure address.\r
+\r
+  @retval EFI_SUCCESS           The protocol was added to ChildHandle.\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources availabe to create\r
+                                the child\r
+  @retval other                 The child handle was not created\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslSocketAllocate (\r
+  IN OUT EFI_HANDLE * pChildHandle,\r
+  IN     UINTN DebugFlags,\r
+  IN OUT DT_SOCKET ** ppSocket\r
+  );\r
+\r
+/**\r
+  Allocate a packet for a receive or transmit operation\r
+\r
+  @param [in] ppPacket      Address to receive the DT_PACKET structure\r
+  @param [in] LengthInBytes Length of the packet structure\r
+  @param [in] DebugFlags    Flags for debug messages\r
+\r
+  @retval EFI_SUCCESS - The packet was allocated successfully\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketPacketAllocate (\r
+  IN DT_PACKET ** ppPacket,\r
+  IN size_t LengthInBytes,\r
+  IN UINTN DebugFlags\r
+  );\r
+\r
+/**\r
+  Free a packet used for receive or transmit operation\r
+\r
+  @param [in] pPacket     Address of the DT_PACKET structure\r
+  @param [in] DebugFlags  Flags for debug messages\r
+\r
+  @retval EFI_SUCCESS - The packet was allocated successfully\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketPacketFree (\r
+  IN DT_PACKET * pPacket,\r
+  IN UINTN DebugFlags\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+// Tcp4 Routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Accept a network connection.\r
+\r
+  The SocketAccept routine waits for a network connection to the socket.\r
+  It is able to return the remote network address to the caller if\r
+  requested.\r
+\r
+  @param [in] pSocket   Address of the socket structure.\r
+\r
+  @param [in] pSockAddr       Address of a buffer to receive the remote\r
+                              network address.\r
+\r
+  @param [in, out] pSockAddrLength  Length in bytes of the address buffer.\r
+                                    On output specifies the length of the\r
+                                    remote network address.\r
+\r
+  @retval EFI_SUCCESS   Remote address is available\r
+  @retval Others        Remote address not available\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpAccept4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN struct sockaddr * pSockAddr,\r
+  IN OUT socklen_t * pSockAddrLength\r
+  );\r
+\r
+/**\r
+  Bind a name to a socket.\r
+\r
+  The ::TcpBind4 routine connects a name to A TCP4 stack on the local machine.\r
+\r
+  @param [in] pSocket   Address of the socket structure.\r
+\r
+  @param [in] pSockAddr Address of a sockaddr structure that contains the\r
+                        connection point on the local machine.  An IPv4 address\r
+                        of INADDR_ANY specifies that the connection is made to\r
+                        all of the network stacks on the platform.  Specifying a\r
+                        specific IPv4 address restricts the connection to the\r
+                        network stack supporting that address.  Specifying zero\r
+                        for the port causes the network layer to assign a port\r
+                        number from the dynamic range.  Specifying a specific\r
+                        port number causes the network layer to use that port.\r
+\r
+  @param [in] SockAddrLen   Specifies the length in bytes of the sockaddr structure.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpBind4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength\r
+  );\r
+\r
+/**\r
+  Poll for completion of the connection attempt.\r
+\r
+  The ::TcpConnectPoll4 routine determines when the connection\r
+  attempt transitions from being in process to being complete.\r
+\r
+  @param [in] pSocket         Address of the socket structure.\r
+\r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpConnectPoll4 (\r
+  IN DT_SOCKET * pSocket\r
+  );\r
+\r
+/**\r
+  Connect to a remote system via the network.\r
+\r
+  The ::TcpConnectStart4= routine starts the connection processing\r
+  for a TCP4 port.\r
+\r
+  @param [in] pSocket         Address of the socket structure.\r
+\r
+  @param [in] pSockAddr       Network address of the remote system.\r
+    \r
+  @param [in] SockAddrLength  Length in bytes of the network address.\r
+  \r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpConnectStart4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength\r
+  );\r
+\r
+/**\r
+  Initialize the TCP4 service.\r
+\r
+  This routine initializes the TCP4 service after its service binding\r
+  protocol was located on a controller.\r
+\r
+  @param [in] pService             DT_SERVICE structure address\r
+\r
+  @retval EFI_SUCCESS          The service was properly initialized\r
+  @retval other                A failure occurred during the service initialization\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslTcpInitialize4 (\r
+  IN DT_SERVICE * pService\r
+  );\r
+\r
+/**\r
+  Get the local socket address\r
+\r
+  @param [in] pSocket             Address of the socket structure.\r
+\r
+  @param [out] pAddress           Network address to receive the local system address\r
+\r
+  @param [in,out] pAddressLength  Length of the local network address structure\r
+\r
+  @retval EFI_SUCCESS - Address available\r
+  @retval Other - Failed to get the address\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpGetLocalAddress4 (\r
+  IN DT_SOCKET * pSocket,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  );\r
+\r
+/**\r
+  Get the remote socket address\r
+\r
+  @param [in] pSocket             Address of the socket structure.\r
+\r
+  @param [out] pAddress           Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Address available\r
+  @retval Other - Failed to get the address\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpGetRemoteAddress4 (\r
+  IN DT_SOCKET * pSocket,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  );\r
+\r
+/**\r
+  Establish the known port to listen for network connections.\r
+\r
+  The ::Tcp4Listen routine places the port into a state that enables connection\r
+  attempts.  Connections are placed into FIFO order in a queue to be serviced\r
+  by the application.  The application calls the ::Tcp4Accept routine to remove\r
+  the next connection from the queue and get the associated socket.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html">POSIX</a>\r
+  documentation for the listen routine is available online for reference.\r
+\r
+  @param [in] pSocket     Address of the socket structure.\r
+  \r
+  @retval EFI_SUCCESS - Socket successfully created\r
+  @retval Other - Failed to enable the socket for listen\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpListen4 (\r
+  IN DT_SOCKET * pSocket\r
+  );\r
+\r
+/**\r
+  Process the connection attempt\r
+\r
+  A system has initiated a connection attempt with a socket in the\r
+  listen state.  Attempt to complete the connection.\r
+\r
+  @param  Event         The listeen completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpListenComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Allocate and initialize a DT_PORT structure.\r
+\r
+  @param [in] pSocket     Address of the socket structure.\r
+  @param [in] pService    Address of the DT_SERVICE structure.\r
+  @param [in] ChildHandle TCP4 child handle\r
+  @param [in] pIpAddress  Buffer containing IP4 network address of the local host\r
+  @param [in] PortNumber  Tcp4 port number\r
+  @param [in] DebugFlags  Flags for debug messages\r
+  @param [out] ppPort     Buffer to receive new DT_PORT structure address\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpPortAllocate4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN DT_SERVICE * pService,\r
+  IN EFI_HANDLE ChildHandle,\r
+  IN CONST UINT8 *pIpAddress,\r
+  IN UINT16 PortNumber,\r
+  IN UINTN DebugFlags,\r
+  OUT DT_PORT ** ppPort\r
+  );\r
+\r
+/**\r
+  Close a TCP4 port.\r
+\r
+  This routine releases the resources allocated by\r
+  ::TcpPortAllocate4().\r
+  \r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS     The port is closed\r
+  @retval other           Port close error\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpPortClose4 (\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Process the port close completion\r
+\r
+  @param  Event         The close completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpPortCloseComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Port close state 3\r
+\r
+  Continue the close operation after the receive is complete.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS         The port is closed\r
+  @retval EFI_NOT_READY       The port is still closing\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpPortCloseRxDone4 (\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Start the close operation on a TCP4 port.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+  @param [in] bAbort      Set TRUE to abort active transfers\r
+  @param [in] DebugFlags  Flags for debug messages\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpPortCloseStart4 (\r
+  IN DT_PORT * pPort,\r
+  IN BOOLEAN bAbort,\r
+  IN UINTN DebugFlags\r
+  );\r
+\r
+/**\r
+  Port close state 2\r
+\r
+  Continue the close operation after the transmission is complete.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_NOT_READY       The port is still closing\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpPortCloseTxDone4 (\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Receive data from a network connection.\r
+\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @param [in] Flags           Message control flags\r
+  \r
+  @param [in] BufferLength    Length of the the buffer\r
+  \r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+  \r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpReceive4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN INT32 Flags,\r
+  IN size_t BufferLength,\r
+  IN UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  );\r
+\r
+/**\r
+  Cancel the receive operations\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @retval EFI_SUCCESS - The cancel was successful\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpRxCancel4 (\r
+  IN DT_SOCKET * pSocket\r
+  );\r
+\r
+/**\r
+  Process the receive completion\r
+\r
+  Buffer the data that was just received.\r
+\r
+  @param  Event         The receive completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpRxComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Start a receive operation\r
+\r
+  @param [in] pPort       Address of the DT_PORT structure.\r
+\r
+ **/\r
+VOID\r
+EslTcpRxStart4 (\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Shutdown the TCP4 service.\r
+\r
+  This routine undoes the work performed by ::TcpInitialize4.\r
+\r
+  @param [in] pService             DT_SERVICE structure address\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EslTcpShutdown4 (\r
+  IN DT_SERVICE * pService\r
+  );\r
+\r
+/**\r
+  Determine if the socket is configured.\r
+\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @retval EFI_SUCCESS - The port is connected\r
+  @retval EFI_NOT_STARTED - The port is not connected\r
+\r
+ **/\r
+ EFI_STATUS\r
+ EslTcpSocketIsConfigured4 (\r
+  IN DT_SOCKET * pSocket\r
+  );\r
+\r
+/**\r
+  Buffer data for transmission over a network connection.\r
+\r
+  This routine is called by the socket layer API to buffer\r
+  data for transmission.  When necessary, this routine will\r
+  start the transmit engine that performs the data transmission\r
+  on the network connection.\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @param [in] Flags           Message control flags\r
+  \r
+  @param [in] BufferLength    Length of the the buffer\r
+  \r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+  \r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully buffered\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpTxBuffer4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN int Flags,\r
+  IN size_t BufferLength,\r
+  IN CONST UINT8 * pBuffer,\r
+  OUT size_t * pDataLength\r
+  );\r
+\r
+/**\r
+  Process the normal data transmit completion\r
+\r
+  @param  Event         The normal transmit completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpTxComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Process the urgent data transmit completion\r
+\r
+  @param  Event         The urgent transmit completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpTxOobComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Transmit data using a network connection.\r
+\r
+\r
+  @param [in] pPort           Address of a DT_PORT structure\r
+  @param [in] pToken          Address of either the OOB or normal transmit token\r
+  @param [in] ppQueueHead     Transmit queue head address\r
+  @param [in] ppQueueTail     Transmit queue tail address\r
+  @param [in] ppPacket        Active transmit packet address\r
+\r
+ **/\r
+VOID\r
+EslTcpTxStart4 (\r
+  IN DT_PORT * pPort,\r
+  IN EFI_TCP4_IO_TOKEN * pToken,\r
+  IN DT_PACKET ** ppQueueHead,\r
+  IN DT_PACKET ** ppQueueTail,\r
+  IN DT_PACKET ** ppPacket\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+// Udp4 Routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Bind a name to a socket.\r
+\r
+  The ::UdpBind4 routine connects a name to a UDP4 stack on the local machine.\r
+\r
+  @param [in] pSocket   Address of the socket structure.\r
+\r
+  @param [in] pSockAddr Address of a sockaddr structure that contains the\r
+                        connection point on the local machine.  An IPv4 address\r
+                        of INADDR_ANY specifies that the connection is made to\r
+                        all of the network stacks on the platform.  Specifying a\r
+                        specific IPv4 address restricts the connection to the\r
+                        network stack supporting that address.  Specifying zero\r
+                        for the port causes the network layer to assign a port\r
+                        number from the dynamic range.  Specifying a specific\r
+                        port number causes the network layer to use that port.\r
+\r
+  @param [in] SockAddrLen   Specifies the length in bytes of the sockaddr structure.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdpBind4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength\r
+  );\r
+\r
+/**\r
+  Initialize the UDP4 service.\r
+\r
+  This routine initializes the UDP4 service after its service binding\r
+  protocol was located on a controller.\r
+\r
+  @param [in] pService        DT_SERVICE structure address\r
+\r
+  @retval EFI_SUCCESS         The service was properly initialized\r
+  @retval other               A failure occurred during the service initialization\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslUdpInitialize4 (\r
+  IN DT_SERVICE * pService\r
+  );\r
+\r
+/**\r
+  Allocate and initialize a DT_PORT structure.\r
+\r
+  @param [in] pSocket     Address of the socket structure.\r
+  @param [in] pService    Address of the DT_SERVICE structure.\r
+  @param [in] ChildHandle Udp4 child handle\r
+  @param [in] pIpAddress  Buffer containing IP4 network address of the local host\r
+  @param [in] PortNumber  Udp4 port number\r
+  @param [in] DebugFlags  Flags for debug messages\r
+  @param [out] ppPort     Buffer to receive new DT_PORT structure address\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdpPortAllocate4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN DT_SERVICE * pService,\r
+  IN EFI_HANDLE ChildHandle,\r
+  IN CONST UINT8 * pIpAddress,\r
+  IN UINT16 PortNumber,\r
+  IN UINTN DebugFlags,\r
+  OUT DT_PORT ** ppPort\r
+  );\r
+\r
+/**\r
+  Close a UDP4 port.\r
+\r
+  This routine releases the resources allocated by\r
+  ::UdpPortAllocate4().\r
+  \r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS     The port is closed\r
+  @retval other           Port close error\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpPortClose4 (\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Start the close operation on a UDP4 port, state 1.\r
+\r
+  Closing a port goes through the following states:\r
+  1. Port close starting - Mark the port as closing and wait for transmission to complete\r
+  2. Port TX close done - Transmissions complete, close the port and abort the receives\r
+  3. Port RX close done - Receive operations complete, close the port\r
+  4. Port closed - Release the port resources\r
+  \r
+  @param [in] pPort       Address of the port structure.\r
+  @param [in] bCloseNow   Set TRUE to abort active transfers\r
+  @param [in] DebugFlags  Flags for debug messages\r
+\r
+  @retval EFI_SUCCESS         The port is closed, not normally returned\r
+  @retval EFI_NOT_READY       The port has started the closing process\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpPortCloseStart4 (\r
+  IN DT_PORT * pPort,\r
+  IN BOOLEAN bCloseNow,\r
+  IN UINTN DebugFlags\r
+  );\r
+\r
+/**\r
+  Port close state 2\r
+\r
+  Continue the close operation after the transmission is complete.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS         The port is closed, not normally returned\r
+  @retval EFI_NOT_READY       The port is still closing\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpPortCloseTxDone4 (\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Connect to a remote system via the network.\r
+\r
+  The ::UdpConnectStart4= routine sets the remote address for the connection.\r
+\r
+  @param [in] pSocket         Address of the socket structure.\r
+\r
+  @param [in] pSockAddr       Network address of the remote system.\r
+    \r
+  @param [in] SockAddrLength  Length in bytes of the network address.\r
+  \r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdpConnect4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength\r
+  );\r
+\r
+/**\r
+  Get the local socket address\r
+\r
+  @param [in] pSocket             Address of the socket structure.\r
+\r
+  @param [out] pAddress           Network address to receive the local system address\r
+\r
+  @param [in,out] pAddressLength  Length of the local network address structure\r
+\r
+  @retval EFI_SUCCESS - Address available\r
+  @retval Other - Failed to get the address\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpGetLocalAddress4 (\r
+  IN DT_SOCKET * pSocket,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  );\r
+\r
+/**\r
+  Get the remote socket address\r
+\r
+  @param [in] pSocket             Address of the socket structure.\r
+\r
+  @param [out] pAddress           Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Address available\r
+  @retval Other - Failed to get the address\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpGetRemoteAddress4 (\r
+  IN DT_SOCKET * pSocket,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  );\r
+\r
+/**\r
+  Receive data from a network connection.\r
+\r
+  To minimize the number of buffer copies, the ::UdpRxComplete4\r
+  routine queues the UDP4 driver's buffer to a list of datagrams\r
+  waiting to be received.  The socket driver holds on to the\r
+  buffers from the UDP4 driver until the application layer requests\r
+  the data or the socket is closed.\r
+\r
+  The application calls this routine in the socket layer to\r
+  receive datagrams from one or more remote systems. This routine\r
+  removes the next available datagram from the list of datagrams\r
+  and copies the data from the UDP4 driver's buffer into the\r
+  application's buffer.  The UDP4 driver's buffer is then returned.\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+\r
+  @param [in] Flags           Message control flags\r
+\r
+  @param [in] BufferLength    Length of the the buffer\r
+\r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+\r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpReceive4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN INT32 Flags,\r
+  IN size_t BufferLength,\r
+  IN UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  );\r
+\r
+/**\r
+  Cancel the receive operations\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @retval EFI_SUCCESS - The cancel was successful\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdpRxCancel4 (\r
+  IN DT_SOCKET * pSocket\r
+  );\r
+\r
+/**\r
+  Process the receive completion\r
+\r
+  Keep the UDP4 driver's buffer and append it to the list of\r
+  datagrams for the application to receive.  The UDP4 driver's\r
+  buffer will be returned by either ::UdpReceive4 or\r
+  ::UdpPortCloseTxDone4.\r
+\r
+  @param  Event         The receive completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslUdpRxComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Start a receive operation\r
+\r
+  @param [in] pPort       Address of the DT_PORT structure.\r
+\r
+ **/\r
+VOID\r
+EslUdpRxStart4 (\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Determine if the socket is configured.\r
+\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @retval EFI_SUCCESS - The port is connected\r
+  @retval EFI_NOT_STARTED - The port is not connected\r
+\r
+ **/\r
+ EFI_STATUS\r
+ EslUdpSocketIsConfigured4 (\r
+  IN DT_SOCKET * pSocket\r
+  );\r
+\r
+/**\r
+  Process the transmit completion\r
+\r
+  @param  Event         The normal transmit completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslUdpTxComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+/**\r
+  Shutdown the UDP4 service.\r
+\r
+  This routine undoes the work performed by ::UdpInitialize4.\r
+\r
+  @param [in] pService        DT_SERVICE structure address\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EslUdpShutdown4 (\r
+  IN DT_SERVICE * pService\r
+  );\r
+\r
+/**\r
+  Buffer data for transmission over a network connection.\r
+\r
+  This routine is called by the socket layer API to buffer\r
+  data for transmission.  The data is copied into a local buffer\r
+  freeing the application buffer for reuse upon return.  When\r
+  necessary, this routine will start the transmit engine that\r
+  performs the data transmission on the network connection.  The\r
+  transmit engine transmits the data a packet at a time over the\r
+  network connection.\r
+\r
+  Transmission errors are returned during the next transmission or\r
+  during the close operation.  Only buffering errors are returned\r
+  during the current transmission attempt.\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+\r
+  @param [in] Flags           Message control flags\r
+\r
+  @param [in] BufferLength    Length of the the buffer\r
+\r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+\r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [in] pAddress        Network address of the remote system address\r
+\r
+  @param [in] AddressLength   Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully buffered\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpTxBuffer4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN int Flags,\r
+  IN size_t BufferLength,\r
+  IN CONST UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  IN const struct sockaddr * pAddress,\r
+  IN socklen_t AddressLength\r
+  );\r
+\r
+/**\r
+  Transmit data using a network connection.\r
+\r
+  @param [in] pPort           Address of a DT_PORT structure\r
+\r
+ **/\r
+VOID\r
+EslUdpTxStart4 (\r
+  IN DT_PORT * pPort\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+#endif  //  _SOCKET_H_\r
diff --git a/StdLib/EfiSocketLib/Tcp4.c b/StdLib/EfiSocketLib/Tcp4.c
new file mode 100644 (file)
index 0000000..2840dd7
--- /dev/null
@@ -0,0 +1,3415 @@
+/** @file\r
+  Implement the TCP4 driver support for the socket layer.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Socket.h"\r
+\r
+\r
+/**\r
+  Accept a network connection.\r
+\r
+  The SocketAccept routine waits for a network connection to the socket.\r
+  It is able to return the remote network address to the caller if\r
+  requested.\r
+\r
+  @param [in] pSocket   Address of the socket structure.\r
+\r
+  @param [in] pSockAddr       Address of a buffer to receive the remote\r
+                              network address.\r
+\r
+  @param [in, out] pSockAddrLength  Length in bytes of the address buffer.\r
+                                    On output specifies the length of the\r
+                                    remote network address.\r
+\r
+  @retval EFI_SUCCESS   Remote address is available\r
+  @retval Others        Remote address not available\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpAccept4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN struct sockaddr * pSockAddr,\r
+  IN OUT socklen_t * pSockAddrLength\r
+  )\r
+{\r
+  DT_PORT * pPort;\r
+  struct sockaddr_in * pRemoteAddress;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  UINT32 RemoteAddress;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Validate the socket length\r
+  //\r
+  pRemoteAddress = (struct sockaddr_in *) pSockAddr;\r
+  if (( NULL == pSockAddrLength )\r
+    || ( sizeof ( *pRemoteAddress ) > *pSockAddrLength )) {\r
+    //\r
+    //  Invalid socket address\r
+    //\r
+    Status = EFI_INVALID_PARAMETER;\r
+    pSocket->errno = EINVAL;\r
+    DEBUG (( DEBUG_ACCEPT,\r
+              "ERROR - Invalid address length\r\n" ));\r
+  }\r
+  else {\r
+    //\r
+    //  Assume success\r
+    //\r
+    Status = EFI_SUCCESS;\r
+\r
+    //\r
+    //  Locate the address context\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    pTcp4 = &pPort->Context.Tcp4;\r
+\r
+    //\r
+    //  Fill-in the remote address structure\r
+    //\r
+    ZeroMem ( pRemoteAddress, sizeof ( *pRemoteAddress ));\r
+    pRemoteAddress->sin_len = sizeof ( *pRemoteAddress );\r
+    pRemoteAddress->sin_family = AF_INET;\r
+    pRemoteAddress->sin_port = SwapBytes16 ( pTcp4->ConfigData.AccessPoint.RemotePort );\r
+    RemoteAddress = pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3];\r
+    RemoteAddress <<= 8;\r
+    RemoteAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2];\r
+    RemoteAddress <<= 8;\r
+    RemoteAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1];\r
+    RemoteAddress <<= 8;\r
+    RemoteAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0];\r
+    pRemoteAddress->sin_addr.s_addr = RemoteAddress;\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Bind a name to a socket.\r
+\r
+  The ::TcpBind4 routine connects a name to a TCP4 stack on the local machine.\r
+\r
+  @param [in] pSocket   Address of the socket structure.\r
+\r
+  @param [in] pSockAddr Address of a sockaddr structure that contains the\r
+                        connection point on the local machine.  An IPv4 address\r
+                        of INADDR_ANY specifies that the connection is made to\r
+                        all of the network stacks on the platform.  Specifying a\r
+                        specific IPv4 address restricts the connection to the\r
+                        network stack supporting that address.  Specifying zero\r
+                        for the port causes the network layer to assign a port\r
+                        number from the dynamic range.  Specifying a specific\r
+                        port number causes the network layer to use that port.\r
+\r
+  @param [in] SockAddrLen   Specifies the length in bytes of the sockaddr structure.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpBind4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength\r
+  )\r
+{\r
+  EFI_HANDLE ChildHandle;\r
+  DT_LAYER * pLayer;\r
+  DT_PORT * pPort;\r
+  DT_SERVICE * pService;\r
+  CONST struct sockaddr_in * pIp4Address;\r
+  EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service;\r
+  EFI_STATUS Status;\r
+  EFI_STATUS TempStatus;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  pSocket->errno = 0;\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Validate the address length\r
+  //\r
+  pIp4Address = (CONST struct sockaddr_in *) pSockAddr;\r
+  if ( SockAddrLength >= ( sizeof ( *pIp4Address )\r
+                           - sizeof ( pIp4Address->sin_zero ))) {\r
+\r
+    //\r
+    //  Walk the list of services\r
+    //\r
+    pLayer = &mEslLayer;\r
+    pService = pLayer->pTcp4List;\r
+    while ( NULL != pService ) {\r
+      //\r
+      //  Create the TCP port\r
+      //\r
+      pTcp4Service = pService->pInterface;\r
+      ChildHandle = NULL;\r
+      Status = pTcp4Service->CreateChild ( pTcp4Service,\r
+                                           &ChildHandle );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
+                  "0x%08x: Tcp4 port handle created\r\n",\r
+                  ChildHandle ));\r
+\r
+        //\r
+        //  Open the port\r
+        //\r
+        Status = EslTcpPortAllocate4 ( pSocket,\r
+                                       pService,\r
+                                       ChildHandle,\r
+                                       (UINT8 *) &pIp4Address->sin_addr.s_addr,\r
+                                       SwapBytes16 ( pIp4Address->sin_port ),\r
+                                       DEBUG_BIND,\r
+                                       &pPort );\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
+                  "ERROR - Failed to open Tcp4 port handle, Status: %r\r\n",\r
+                  Status ));\r
+        ChildHandle = NULL;\r
+      }\r
+\r
+      //\r
+      //  Close the port if necessary\r
+      //\r
+      if (( EFI_ERROR ( Status )) && ( NULL != ChildHandle )) {\r
+        TempStatus = pTcp4Service->DestroyChild ( pTcp4Service,\r
+                                                  ChildHandle );\r
+        if ( !EFI_ERROR ( TempStatus )) {\r
+          DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
+                    "0x%08x: Tcp4 port handle destroyed\r\n",\r
+                    ChildHandle ));\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_ERROR | DEBUG_BIND | DEBUG_POOL,\r
+                    "ERROR - Failed to destroy the Tcp4 port handle 0x%08x, Status: %r\r\n",\r
+                    ChildHandle,\r
+                    TempStatus ));\r
+          ASSERT ( EFI_SUCCESS == TempStatus );\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Set the next service\r
+      //\r
+      pService = pService->pNext;\r
+    }\r
+\r
+    //\r
+    //  Verify that at least one network connection was found\r
+    //\r
+    if ( NULL == pSocket->pPortList ) {\r
+      DEBUG (( DEBUG_BIND | DEBUG_POOL | DEBUG_INIT,\r
+                "Socket address %d.%d.%d.%d (0x%08x) is not available!\r\n",\r
+                ( pIp4Address->sin_addr.s_addr >> 24 ) & 0xff,\r
+                ( pIp4Address->sin_addr.s_addr >> 16 ) & 0xff,\r
+                ( pIp4Address->sin_addr.s_addr >> 8 ) & 0xff,\r
+                pIp4Address->sin_addr.s_addr & 0xff,\r
+                pIp4Address->sin_addr.s_addr ));\r
+      pSocket->errno = EADDRNOTAVAIL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_BIND,\r
+              "ERROR - Invalid TCP4 address length: %d\r\n",\r
+              SockAddrLength ));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    pSocket->errno = EINVAL;\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Attempt to connect to a remote TCP port\r
+\r
+  @param [in] pSocket         Address of the socket structure.\r
+\r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpConnectAttempt4 (\r
+  IN DT_SOCKET * pSocket\r
+  )\r
+{\r
+  DT_PORT * pPort;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Determine if any more local adapters are available\r
+  //\r
+  pPort = pSocket->pPortList;\r
+  if ( NULL != pPort ) {\r
+    //\r
+    //  Configure the port\r
+    //\r
+    pTcp4 = &pPort->Context.Tcp4;\r
+    pTcp4->ConfigData.AccessPoint.ActiveFlag = TRUE;\r
+    pTcp4->ConfigData.TimeToLive = 255;\r
+    pTcp4Protocol = pTcp4->pProtocol;\r
+    Status = pTcp4Protocol->Configure ( pTcp4Protocol,\r
+                                        &pTcp4->ConfigData );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_CONNECT,\r
+                "ERROR - Failed to configure the Tcp4 port, Status: %r\r\n",\r
+                Status ));\r
+      switch ( Status ) {\r
+      case EFI_ACCESS_DENIED:\r
+        pSocket->errno = EACCES;\r
+        break;\r
+    \r
+      default:\r
+      case EFI_DEVICE_ERROR:\r
+        pSocket->errno = EIO;\r
+        break;\r
+    \r
+      case EFI_INVALID_PARAMETER:\r
+        pSocket->errno = EADDRNOTAVAIL;\r
+        break;\r
+    \r
+      case EFI_NO_MAPPING:\r
+        pSocket->errno = EAFNOSUPPORT;\r
+        break;\r
+    \r
+      case EFI_OUT_OF_RESOURCES:\r
+        pSocket->errno = ENOBUFS;\r
+        break;\r
+    \r
+      case EFI_UNSUPPORTED:\r
+        pSocket->errno = EOPNOTSUPP;\r
+        break;\r
+      }\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_CONNECT,\r
+                "0x%08x: Port configured\r\n",\r
+                pPort ));\r
+      pTcp4->bConfigured = TRUE;\r
+\r
+      //\r
+      //  Attempt the connection to the remote system\r
+      //\r
+      Status = pTcp4Protocol->Connect ( pTcp4Protocol,\r
+                                        &pTcp4->ConnectToken );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        //\r
+        //  Connection in progress\r
+        //\r
+        pSocket->errno = EINPROGRESS;\r
+        Status = EFI_NOT_READY;\r
+        DEBUG (( DEBUG_CONNECT,\r
+                  "0x%08x: Port attempting connection to %d.%d.%d.%d:%d\r\n",\r
+                  pPort,\r
+                  pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
+                  pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
+                  pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
+                  pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
+                  pTcp4->ConfigData.AccessPoint.RemotePort ));\r
+      }\r
+      else {\r
+        //\r
+        //  Connection error\r
+        //\r
+        pSocket->errno = EINVAL;\r
+        DEBUG (( DEBUG_CONNECT,\r
+                  "ERROR - Port 0x%08x not connected, Status: %r\r\n",\r
+                  pPort,\r
+                  Status ));\r
+      }\r
+    }\r
+  }\r
+  else {\r
+    //\r
+    //  No more local adapters available\r
+    //\r
+    pSocket->errno = ENETUNREACH;\r
+    Status = EFI_NO_RESPONSE;\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Process the remote connection attempt\r
+\r
+  A connection attempt to a remote system has just completed when\r
+  this routine is invoked.  Release the port in the case of an\r
+  error and start a connection attempt on the next port.  If the\r
+  connection attempt was successful, then release all of the other\r
+  ports.\r
+\r
+  @param  Event         The connect completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpConnectComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  BOOLEAN bRemoveFirstPort;\r
+  BOOLEAN bRemovePorts;\r
+  DT_PORT * pNextPort;\r
+  DT_SOCKET * pSocket;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Locate the TCP context\r
+  //\r
+  pSocket = pPort->pSocket;\r
+  pTcp4 = &pPort->Context.Tcp4;\r
+\r
+  //\r
+  //  Get the connection status\r
+  //\r
+  bRemoveFirstPort = FALSE;\r
+  bRemovePorts = FALSE;\r
+  Status = pTcp4->ConnectToken.CompletionToken.Status;\r
+  pSocket->ConnectStatus = Status;\r
+  if ( !EFI_ERROR ( Status )) {\r
+    //\r
+    //  The connection was successful\r
+    //\r
+    DEBUG (( DEBUG_CONNECT,\r
+              "0x%08x: Port connected to %d.%d.%d.%d:%d\r\n",\r
+              pPort,\r
+              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr [0],\r
+              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr [1],\r
+              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr [2],\r
+              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr [3],\r
+              pTcp4->ConfigData.AccessPoint.RemotePort ));\r
+\r
+    //\r
+    //  Remove the rest of the ports\r
+    //\r
+    bRemovePorts = TRUE;\r
+  }\r
+  else {\r
+    //\r
+    //  The connection failed\r
+    //\r
+    DEBUG (( DEBUG_CONNECT,\r
+              "0x%08x: Port connection to %d.%d.%d.%d:%d failed, Status: %r\r\n",\r
+              pPort,\r
+              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr [0],\r
+              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr [1],\r
+              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr [2],\r
+              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr [3],\r
+              pTcp4->ConfigData.AccessPoint.RemotePort,\r
+              Status ));\r
+\r
+    //\r
+    //  Close the current port\r
+    //\r
+    Status = EslTcpPortClose4 ( pPort );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_CONNECT,\r
+              "0x%08x: Port closed\r\n",\r
+              pPort ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_CONNECT,\r
+                "ERROR - Failed to close port 0x%08x, Status: %r\r\n",\r
+                pPort,\r
+                Status ));\r
+    }\r
+\r
+    //\r
+    //  Try to connect using the next port\r
+    //\r
+    Status = EslTcpConnectAttempt4 ( pSocket );\r
+    if ( EFI_NOT_READY != Status ) {\r
+      pSocket->ConnectStatus = Status;\r
+      bRemoveFirstPort = TRUE;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Remove the ports if necessary\r
+  //\r
+  if ( bRemoveFirstPort || bRemovePorts ) {\r
+    //\r
+    //  Remove the first port if necessary\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    if (( !bRemoveFirstPort ) && ( NULL != pPort )) {\r
+      pPort = pPort->pLinkSocket;\r
+    }\r
+\r
+    //\r
+    //  Remove the rest of the list\r
+    //\r
+    while ( NULL != pPort ) {\r
+      pNextPort = pPort->pLinkSocket;\r
+      EslTcpPortClose4 ( pPort );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_CONNECT,\r
+                "0x%08x: Port closed\r\n",\r
+                pPort ));\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_CONNECT,\r
+                  "ERROR - Failed to close port 0x%08x, Status: %r\r\n",\r
+                  pPort,\r
+                  Status ));\r
+      }\r
+      pPort = pNextPort;\r
+    }\r
+\r
+    //\r
+    //  Notify the poll routine\r
+    //\r
+    pSocket->bConnected = TRUE;\r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Poll for completion of the connection attempt.\r
+\r
+  The ::TcpConnectPoll4 routine determines when the connection\r
+  attempt transitions from being in process to being complete.\r
+\r
+  @param [in] pSocket         Address of the socket structure.\r
+\r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpConnectPoll4 (\r
+  IN DT_SOCKET * pSocket\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Determine if the connection is complete\r
+  //\r
+  if ( !pSocket->bConnected ) {\r
+    //\r
+    //  Not connected\r
+    //\r
+    pSocket->errno = EAGAIN;\r
+    Status = EFI_NOT_READY;\r
+  }\r
+  else {\r
+    //\r
+    //  The connection processing is complete\r
+    //\r
+    pSocket->bConnected = FALSE;\r
+\r
+    //\r
+    //  Translate the connection status\r
+    //\r
+    Status = pSocket->ConnectStatus;\r
+    switch ( Status ) {\r
+    default:\r
+    case EFI_DEVICE_ERROR:\r
+      pSocket->errno = EIO;\r
+      break;\r
+\r
+    case EFI_ABORTED:\r
+      pSocket->errno = ECONNREFUSED;\r
+      break;\r
+\r
+    case EFI_INVALID_PARAMETER:\r
+      pSocket->errno = EINVAL;\r
+      break;\r
+\r
+    case EFI_NO_MAPPING:\r
+    case EFI_NO_RESPONSE:\r
+      pSocket->errno = EHOSTUNREACH;\r
+      break;\r
+\r
+    case EFI_NO_MEDIA:\r
+      pSocket->errno = ENETDOWN;\r
+      break;\r
+\r
+    case EFI_OUT_OF_RESOURCES:\r
+      pSocket->errno = ENOMEM;\r
+      break;\r
+\r
+    case EFI_SUCCESS:\r
+      pSocket->errno = 0;\r
+      pSocket->bConfigured = TRUE;\r
+      break;\r
+\r
+    case EFI_TIMEOUT:\r
+      pSocket->errno = ETIMEDOUT;\r
+      break;\r
+\r
+    case EFI_UNSUPPORTED:\r
+      pSocket->errno = ENOTSUP;\r
+      break;\r
+\r
+    case 0x80000069:\r
+      pSocket->errno = ECONNRESET;\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the initialization status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Connect to a remote system via the network.\r
+\r
+  The ::TcpConnectStart4= routine starts the connection processing\r
+  for a TCP4 port.\r
+\r
+  @param [in] pSocket         Address of the socket structure.\r
+\r
+  @param [in] pSockAddr       Network address of the remote system.\r
+    \r
+  @param [in] SockAddrLength  Length in bytes of the network address.\r
+  \r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpConnectStart4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength\r
+  )\r
+{\r
+  struct sockaddr_in LocalAddress;\r
+  DT_PORT * pPort;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  CONST struct sockaddr_in * pIp4Address;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Validate the address length\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  pIp4Address = (CONST struct sockaddr_in *) pSockAddr;\r
+  if ( SockAddrLength >= ( sizeof ( *pIp4Address )\r
+                           - sizeof ( pIp4Address->sin_zero ))) {\r
+    //\r
+    //  Determine if BIND was already called\r
+    //\r
+    if ( NULL == pSocket->pPortList ) {\r
+      //\r
+      //  Allow any local port\r
+      //\r
+      ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));\r
+      LocalAddress.sin_len = sizeof ( LocalAddress );\r
+      LocalAddress.sin_family = AF_INET;\r
+      Status = EslSocketBind ( &pSocket->SocketProtocol,\r
+                               (struct sockaddr *)&LocalAddress,\r
+                               LocalAddress.sin_len,\r
+                               &pSocket->errno );\r
+    }\r
+    if ( NULL != pSocket->pPortList ) {\r
+      //\r
+      //  Walk the list of ports\r
+      //\r
+      pPort = pSocket->pPortList;\r
+      while ( NULL != pPort ) {\r
+        //\r
+        //  Set the remote address\r
+        //\r
+        pTcp4 = &pPort->Context.Tcp4;\r
+        *(UINT32 *)&pTcp4->ConfigData.AccessPoint.RemoteAddress = pIp4Address->sin_addr.s_addr;\r
+        pTcp4->ConfigData.AccessPoint.RemotePort = SwapBytes16 ( pIp4Address->sin_port );\r
+\r
+        //\r
+        //  Set the next port\r
+        //\r
+        pPort = pPort->pLinkSocket;\r
+      }\r
+      \r
+      //\r
+      //  Attempt a connection using the first adapter\r
+      //\r
+      Status = EslTcpConnectAttempt4 ( pSocket );\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_CONNECT,\r
+              "ERROR - Invalid TCP4 address length: %d\r\n",\r
+              SockAddrLength ));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    pSocket->errno = EINVAL;\r
+  }\r
+\r
+  //\r
+  //  Return the initialization status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Initialize the TCP4 service.\r
+\r
+  This routine initializes the TCP4 service after its service binding\r
+  protocol was located on a controller.\r
+\r
+  @param [in] pService        DT_SERVICE structure address\r
+\r
+  @retval EFI_SUCCESS         The service was properly initialized\r
+  @retval other               A failure occurred during the service initialization\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslTcpInitialize4 (\r
+  IN DT_SERVICE * pService\r
+  )\r
+{\r
+  DT_LAYER * pLayer;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Identify the service\r
+  //\r
+  pService->NetworkType = NETWORK_TYPE_TCP4;\r
+\r
+  //\r
+  //  Connect this service to the service list\r
+  //\r
+  pLayer = &mEslLayer;\r
+  pService->pNext = pLayer->pTcp4List;\r
+  pLayer->pTcp4List = pService;\r
+\r
+  //\r
+  //  Assume the list is empty\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Return the initialization status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Get the local socket address\r
+\r
+  @param [in] pSocket             Address of the socket structure.\r
+\r
+  @param [out] pAddress           Network address to receive the local system address\r
+\r
+  @param [in,out] pAddressLength  Length of the local network address structure\r
+\r
+  @retval EFI_SUCCESS - Address available\r
+  @retval Other - Failed to get the address\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpGetLocalAddress4 (\r
+  IN DT_SOCKET * pSocket,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  )\r
+{\r
+  socklen_t LengthInBytes;\r
+  DT_PORT * pPort;\r
+  struct sockaddr_in * pLocalAddress;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Verify that there is just a single connection\r
+  //\r
+  pPort = pSocket->pPortList;\r
+  if (( NULL != pPort ) && ( NULL == pPort->pLinkSocket )) {\r
+    //\r
+    //  Verify the address length\r
+    //\r
+    LengthInBytes = sizeof ( struct sockaddr_in );\r
+    if ( LengthInBytes <= * pAddressLength ) {\r
+      //\r
+      //  Return the local address\r
+      //\r
+      pTcp4 = &pPort->Context.Tcp4;\r
+      pLocalAddress = (struct sockaddr_in *)pAddress;\r
+      ZeroMem ( pLocalAddress, LengthInBytes );\r
+      pLocalAddress->sin_family = AF_INET;\r
+      pLocalAddress->sin_len = (uint8_t)LengthInBytes;\r
+      pLocalAddress->sin_port = SwapBytes16 ( pTcp4->ConfigData.AccessPoint.StationPort );\r
+      CopyMem ( &pLocalAddress->sin_addr,\r
+                &pTcp4->ConfigData.AccessPoint.StationAddress.Addr[0],\r
+                sizeof ( pLocalAddress->sin_addr ));\r
+      pSocket->errno = 0;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+    else {\r
+      pSocket->errno = EINVAL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  else {\r
+    pSocket->errno = ENOTCONN;\r
+    Status = EFI_NOT_STARTED;\r
+  }\r
+  \r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Get the remote socket address\r
+\r
+  @param [in] pSocket             Address of the socket structure.\r
+\r
+  @param [out] pAddress           Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Address available\r
+  @retval Other - Failed to get the address\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpGetRemoteAddress4 (\r
+  IN DT_SOCKET * pSocket,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  )\r
+{\r
+  socklen_t LengthInBytes;\r
+  DT_PORT * pPort;\r
+  struct sockaddr_in * pRemoteAddress;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Verify that there is just a single connection\r
+  //\r
+  pPort = pSocket->pPortList;\r
+  if (( NULL != pPort ) && ( NULL == pPort->pLinkSocket )) {\r
+    //\r
+    //  Verify the address length\r
+    //\r
+    LengthInBytes = sizeof ( struct sockaddr_in );\r
+    if ( LengthInBytes <= * pAddressLength ) {\r
+      //\r
+      //  Return the local address\r
+      //\r
+      pTcp4 = &pPort->Context.Tcp4;\r
+      pRemoteAddress = (struct sockaddr_in *)pAddress;\r
+      ZeroMem ( pRemoteAddress, LengthInBytes );\r
+      pRemoteAddress->sin_family = AF_INET;\r
+      pRemoteAddress->sin_len = (uint8_t)LengthInBytes;\r
+      pRemoteAddress->sin_port = SwapBytes16 ( pTcp4->ConfigData.AccessPoint.RemotePort );\r
+      CopyMem ( &pRemoteAddress->sin_addr,\r
+                &pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
+                sizeof ( pRemoteAddress->sin_addr ));\r
+      pSocket->errno = 0;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+    else {\r
+      pSocket->errno = EINVAL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  else {\r
+    pSocket->errno = ENOTCONN;\r
+    Status = EFI_NOT_STARTED;\r
+  }\r
+  \r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Establish the known port to listen for network connections.\r
+\r
+  The ::Tcp4Listen routine places the port into a state that enables connection\r
+  attempts.  Connections are placed into FIFO order in a queue to be serviced\r
+  by the application.  The application calls the ::Tcp4Accept routine to remove\r
+  the next connection from the queue and get the associated socket.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html">POSIX</a>\r
+  documentation for the listen routine is available online for reference.\r
+\r
+  @param [in] pSocket     Address of the socket structure.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+  @retval Other - Failed to enable the socket for listen\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpListen4 (\r
+  IN DT_SOCKET * pSocket\r
+  )\r
+{\r
+  DT_PORT * pNextPort;\r
+  DT_PORT * pPort;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Use for/break instead of goto\r
+  //\r
+  for ( ; ; ) {\r
+    //\r
+    //  Assume no ports are available\r
+    //\r
+    pSocket->errno = EOPNOTSUPP;\r
+    Status = EFI_NOT_READY;\r
+\r
+    //\r
+    //  Walk the list of ports\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    while ( NULL != pPort ) {\r
+      //\r
+      //  Assume success\r
+      //\r
+      pSocket->errno = 0;\r
+\r
+      //\r
+      //  Use for/break insteak of goto\r
+      //\r
+      for ( ; ; ) {\r
+        //\r
+        //  Create the listen completion event\r
+        //\r
+        pTcp4 = &pPort->Context.Tcp4;\r
+        Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL,\r
+                                    TPL_SOCKETS,\r
+                                    (EFI_EVENT_NOTIFY)EslTcpListenComplete4,\r
+                                    pPort,\r
+                                    &pTcp4->ListenToken.CompletionToken.Event );\r
+        if ( EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_ERROR | DEBUG_LISTEN,\r
+                    "ERROR - Failed to create the listen completion event, Status: %r\r\n",\r
+                    Status ));\r
+          pSocket->errno = ENOMEM;\r
+          break;\r
+        }\r
+        DEBUG (( DEBUG_POOL,\r
+                  "0x%08x: Created listen completion event\r\n",\r
+                  pTcp4->ListenToken.CompletionToken.Event ));\r
+\r
+        //\r
+        //  Configure the port\r
+        //\r
+        pTcp4Protocol = pTcp4->pProtocol;\r
+        Status = pTcp4Protocol->Configure ( pTcp4Protocol,\r
+                                            &pTcp4->ConfigData );\r
+        if ( EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_LISTEN,\r
+                    "ERROR - Failed to configure the Tcp4 port, Status: %r\r\n",\r
+                    Status ));\r
+          switch ( Status ) {\r
+          case EFI_ACCESS_DENIED:\r
+            pSocket->errno = EACCES;\r
+            break;\r
+\r
+          default:\r
+          case EFI_DEVICE_ERROR:\r
+            pSocket->errno = EIO;\r
+            break;\r
+\r
+          case EFI_INVALID_PARAMETER:\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\r
+\r
+          case EFI_NO_MAPPING:\r
+            pSocket->errno = EAFNOSUPPORT;\r
+            break;\r
+\r
+          case EFI_OUT_OF_RESOURCES:\r
+            pSocket->errno = ENOBUFS;\r
+            break;\r
+\r
+          case EFI_UNSUPPORTED:\r
+            pSocket->errno = EOPNOTSUPP;\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+        DEBUG (( DEBUG_LISTEN,\r
+                  "0x%08x: Port configured\r\n",\r
+                  pPort ));\r
+        pTcp4->bConfigured = TRUE;\r
+\r
+        //\r
+        //  Start the listen operation on the port\r
+        //\r
+        Status = pTcp4Protocol->Accept ( pTcp4Protocol,\r
+                                         &pTcp4->ListenToken );\r
+        if ( EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_LISTEN,\r
+                    "ERROR - Failed Tcp4 accept, Status: %r\r\n",\r
+                    Status ));\r
+          switch ( Status ) {\r
+          case EFI_ACCESS_DENIED:\r
+            pSocket->errno = EACCES;\r
+            break;\r
+\r
+          default:\r
+          case EFI_DEVICE_ERROR:\r
+            pSocket->errno = EIO;\r
+            break;\r
+\r
+          case EFI_INVALID_PARAMETER:\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\r
+\r
+          case EFI_NOT_STARTED:\r
+            pSocket->errno = ENETDOWN;\r
+            break;\r
+\r
+          case EFI_OUT_OF_RESOURCES:\r
+            pSocket->errno = ENOBUFS;\r
+            break;\r
+          }\r
+          break;\r
+        }\r
+        DEBUG (( DEBUG_LISTEN,\r
+                  "0x%08x: Listen pending on Port\r\n",\r
+                  pPort ));\r
+\r
+        //\r
+        //  Listen is pending on this port\r
+        //\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Get the next port\r
+      //\r
+      pNextPort = pPort->pLinkSocket;\r
+\r
+      //\r
+      //  Close the port upon error\r
+      //\r
+      if ( EFI_ERROR ( Status ))\r
+      {\r
+        EslTcpPortCloseStart4 ( pPort, TRUE, DEBUG_LISTEN );\r
+      }\r
+\r
+      //\r
+      //  Set the next port\r
+      //\r
+      pPort = pNextPort;\r
+    }\r
+    \r
+    //\r
+    //  Determine if any ports are in the listen state\r
+    //\r
+    if ( NULL == pSocket->pPortList ) {\r
+      //\r
+      //  No ports in the listen state\r
+      //\r
+      pSocket->MaxFifoDepth = 0;\r
+\r
+      //\r
+      //  Return the last error detected\r
+      //\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Mark the socket as configured\r
+    //\r
+    pSocket->bConfigured = TRUE;\r
+\r
+    //\r
+    //  All done\r
+    //\r
+    DEBUG (( DEBUG_LISTEN,\r
+              "0x%08x: pSocket - Listen pending on socket\r\n",\r
+              pSocket ));\r
+    break;\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Process the connection attempt\r
+\r
+  A system has initiated a connection attempt with a socket in the\r
+  listen state.  Attempt to complete the connection.\r
+\r
+  @param  Event         The listen completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpListenComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  EFI_HANDLE ChildHandle;\r
+  EFI_TCP4_CONFIG_DATA * pConfigData;\r
+  DT_LAYER * pLayer;\r
+  DT_PORT * pNewPort;\r
+  DT_SOCKET * pNewSocket;\r
+  DT_SOCKET * pSocket;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
+  EFI_STATUS Status;\r
+  EFI_HANDLE TcpPortHandle;\r
+  EFI_STATUS TempStatus;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Determine if this connection fits into the connection FIFO\r
+  //\r
+  pSocket = pPort->pSocket;\r
+  TcpPortHandle = pPort->Context.Tcp4.ListenToken.NewChildHandle;\r
+  if (( SOCKET_STATE_LISTENING == pSocket->State )\r
+    && ( pSocket->MaxFifoDepth > pSocket->FifoDepth )) {\r
+    //\r
+    //  Allocate a socket for this connection\r
+    //\r
+    ChildHandle = NULL;\r
+    pLayer = &mEslLayer;\r
+    Status = EslSocketAllocate ( &ChildHandle,\r
+                                 DEBUG_CONNECTION,\r
+                                 &pNewSocket );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Clone the socket parameters\r
+      //\r
+      pNewSocket->Domain = pSocket->Domain;\r
+      pNewSocket->Protocol = pSocket->Protocol;\r
+      pNewSocket->Type = pSocket->Type;\r
+\r
+      //\r
+      //  Allocate a port for this connection\r
+      //\r
+      pTcp4 = &pPort->Context.Tcp4;\r
+      Status = EslTcpPortAllocate4 ( pNewSocket,\r
+                                     pPort->pService,\r
+                                     TcpPortHandle,\r
+                                     &pTcp4->ConfigData.AccessPoint.StationAddress.Addr[0],\r
+                                     0,\r
+                                     DEBUG_CONNECTION,\r
+                                     &pNewPort );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        //\r
+        //  Restart the listen operation on the port\r
+        //\r
+        pTcp4Protocol = pTcp4->pProtocol;\r
+        Status = pTcp4Protocol->Accept ( pTcp4Protocol,\r
+                                         &pTcp4->ListenToken );\r
+\r
+        //\r
+        //  Close the TCP port using SocketClose\r
+        //\r
+        TcpPortHandle = NULL;\r
+        pTcp4 = &pNewPort->Context.Tcp4;\r
+        pTcp4->bConfigured = TRUE;\r
+\r
+        //\r
+        //  Check for an accept call error\r
+        //\r
+        if ( !EFI_ERROR ( Status )) {\r
+          //\r
+          //  Get the port configuration\r
+          //\r
+          pConfigData = &pTcp4->ConfigData;\r
+          pConfigData->ControlOption = &pTcp4->Option;\r
+          pTcp4Protocol = pTcp4->pProtocol;\r
+          Status = pTcp4Protocol->GetModeData ( pTcp4Protocol,\r
+                                                NULL,\r
+                                                pConfigData,\r
+                                                NULL,\r
+                                                NULL,\r
+                                                NULL );\r
+          if ( !EFI_ERROR ( Status )) {\r
+            //\r
+            //  Add the new socket to the connection FIFO\r
+            //\r
+            if ( NULL == pSocket->pFifoTail ) {\r
+              //\r
+              //  First connection\r
+              //\r
+              pSocket->pFifoHead = pNewSocket;\r
+            }\r
+            else {\r
+              //\r
+              //  Add to end of list.\r
+              //\r
+              pSocket->pFifoTail->pNextConnection = pNewSocket;\r
+            }\r
+            pSocket->pFifoTail = pNewSocket;\r
+            pSocket->FifoDepth += 1;\r
+\r
+            //\r
+            //  Update the socket state\r
+            //\r
+            pNewSocket->State = SOCKET_STATE_IN_FIFO;\r
+\r
+            //\r
+            //  Log the connection\r
+            //\r
+            DEBUG (( DEBUG_CONNECTION | DEBUG_INFO,\r
+                      "0x%08x: Socket on port %d.%d.%d.%d:%d connected to %d.%d.%d.%d:%d\r\n",\r
+                      pNewSocket,\r
+                      pConfigData->AccessPoint.StationAddress.Addr[0],\r
+                      pConfigData->AccessPoint.StationAddress.Addr[1],\r
+                      pConfigData->AccessPoint.StationAddress.Addr[2],\r
+                      pConfigData->AccessPoint.StationAddress.Addr[3],\r
+                      pConfigData->AccessPoint.StationPort,\r
+                      pConfigData->AccessPoint.RemoteAddress.Addr[0],\r
+                      pConfigData->AccessPoint.RemoteAddress.Addr[1],\r
+                      pConfigData->AccessPoint.RemoteAddress.Addr[2],\r
+                      pConfigData->AccessPoint.RemoteAddress.Addr[3],\r
+                      pConfigData->AccessPoint.RemotePort ));\r
+            DEBUG (( DEBUG_CONNECTION | DEBUG_INFO,\r
+                      "0x%08x: Listen socket adding socket 0x%08x to FIFO, depth: %d\r\n",\r
+                      pSocket,\r
+                      pNewSocket,\r
+                      pSocket->FifoDepth ));\r
+\r
+            //\r
+            //  Start the receive operation\r
+            //\r
+            EslTcpRxStart4 ( pNewPort );\r
+          }\r
+          else {\r
+            DEBUG (( DEBUG_ERROR | DEBUG_CONNECTION | DEBUG_INFO,\r
+                      "ERROR - GetModeData failed on port 0x%08x, Status: %r\r\n",\r
+                      pNewPort,\r
+                      Status ));\r
+          }\r
+        }\r
+        else {\r
+          //\r
+          //  The listen failed on this port\r
+          //\r
+          DEBUG (( DEBUG_LISTEN | DEBUG_INFO,\r
+                    "ERROR - Listen failed on port 0x%08x, Status: %r\r\n",\r
+                    pPort,\r
+                    Status ));\r
+\r
+          //\r
+          //  Close the listening port\r
+          //\r
+          EslTcpPortCloseStart4 ( pPort, TRUE, DEBUG_LISTEN );\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Done with the socket if necessary\r
+      //\r
+      if ( EFI_ERROR ( Status )) {\r
+        TempStatus = EslSocketCloseStart ( &pNewSocket->SocketProtocol,\r
+                                           TRUE,\r
+                                           &pSocket->errno );\r
+        ASSERT ( EFI_SUCCESS == TempStatus );\r
+      }\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_CONNECTION,\r
+              "0x%08x: Socket FIFO full, connection refused\r\n",\r
+              pSocket ));\r
+\r
+    //\r
+    //  The FIFO is full or the socket is in the wrong state\r
+    //\r
+    Status = EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  //\r
+  //  Close the connection if necessary\r
+  //\r
+  if (( EFI_ERROR ( Status ))\r
+    && ( NULL == TcpPortHandle )) {\r
+    //\r
+    // TODO: Finish this code path\r
+    //  The new connection does not fit into the connection FIFO\r
+    //\r
+    //  Process:\r
+    //    Call close\r
+    //    Release the resources\r
+    \r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Allocate and initialize a DT_PORT structure.\r
+\r
+  @param [in] pSocket     Address of the socket structure.\r
+  @param [in] pService    Address of the DT_SERVICE structure.\r
+  @param [in] ChildHandle TCP4 child handle\r
+  @param [in] pIpAddress  Buffer containing IP4 network address of the local host\r
+  @param [in] PortNumber  Tcp4 port number\r
+  @param [in] DebugFlags  Flags for debug messages\r
+  @param [out] ppPort     Buffer to receive new DT_PORT structure address\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpPortAllocate4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN DT_SERVICE * pService,\r
+  IN EFI_HANDLE ChildHandle,\r
+  IN CONST UINT8 * pIpAddress,\r
+  IN UINT16 PortNumber,\r
+  IN UINTN DebugFlags,\r
+  OUT DT_PORT ** ppPort\r
+  )\r
+{\r
+  UINTN LengthInBytes;\r
+  EFI_TCP4_ACCESS_POINT * pAccessPoint;\r
+  DT_LAYER * pLayer;\r
+  DT_PORT * pPort;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Use for/break instead of goto\r
+  for ( ; ; ) {\r
+    //\r
+    //  Allocate a port structure\r
+    //\r
+    pLayer = &mEslLayer;\r
+    LengthInBytes = sizeof ( *pPort );\r
+    Status = gBS->AllocatePool ( EfiRuntimeServicesData,\r
+                                 LengthInBytes,\r
+                                 (VOID **)&pPort );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+                "ERROR - Failed to allocate the port structure, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      pPort = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+              "0x%08x: Allocate pPort, %d bytes\r\n",\r
+              pPort,\r
+              LengthInBytes ));\r
+\r
+    //\r
+    //  Initialize the port\r
+    //\r
+    ZeroMem ( pPort, LengthInBytes );\r
+    pPort->Signature = PORT_SIGNATURE;\r
+    pPort->pService = pService;\r
+    pPort->pSocket = pSocket;\r
+    pPort->pfnCloseStart = EslTcpPortCloseStart4;\r
+    pPort->DebugFlags = DebugFlags;\r
+\r
+    //\r
+    //  Allocate the receive event\r
+    //\r
+    pTcp4 = &pPort->Context.Tcp4;\r
+    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
+                                 TPL_SOCKETS,\r
+                                 (EFI_EVENT_NOTIFY)EslTcpRxComplete4,\r
+                                 pPort,\r
+                                 &pTcp4->RxToken.CompletionToken.Event);\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to create the receive event, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_RX | DEBUG_POOL,\r
+              "0x%08x: Created receive event\r\n",\r
+              pTcp4->RxToken.CompletionToken.Event ));\r
+\r
+    //\r
+    //  Allocate the urgent transmit event\r
+    //\r
+    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
+                                 TPL_SOCKETS,\r
+                                 (EFI_EVENT_NOTIFY)EslTcpTxOobComplete4,\r
+                                 pPort,\r
+                                 &pTcp4->TxOobToken.CompletionToken.Event);\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to create the urgent transmit event, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_CLOSE | DEBUG_POOL,\r
+              "0x%08x: Created urgent transmit event\r\n",\r
+              pTcp4->TxOobToken.CompletionToken.Event ));\r
+\r
+    //\r
+    //  Allocate the normal transmit event\r
+    //\r
+    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
+                                 TPL_SOCKETS,\r
+                                 (EFI_EVENT_NOTIFY)EslTcpTxComplete4,\r
+                                 pPort,\r
+                                 &pTcp4->TxToken.CompletionToken.Event);\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to create the normal transmit event, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_CLOSE | DEBUG_POOL,\r
+              "0x%08x: Created normal transmit event\r\n",\r
+              pTcp4->TxToken.CompletionToken.Event ));\r
+\r
+    //\r
+    //  Allocate the close event\r
+    //\r
+    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
+                                 TPL_SOCKETS,\r
+                                 (EFI_EVENT_NOTIFY)EslTcpPortCloseComplete4,\r
+                                 pPort,\r
+                                 &pTcp4->CloseToken.CompletionToken.Event);\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to create the close event, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_CLOSE | DEBUG_POOL,\r
+              "0x%08x: Created close event\r\n",\r
+              pTcp4->CloseToken.CompletionToken.Event ));\r
+\r
+    //\r
+    //  Allocate the connection event\r
+    //\r
+    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
+                                 TPL_SOCKETS,\r
+                                 (EFI_EVENT_NOTIFY)EslTcpConnectComplete4,\r
+                                 pPort,\r
+                                 &pTcp4->ConnectToken.CompletionToken.Event);\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to create the connect event, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_CLOSE | DEBUG_POOL,\r
+              "0x%08x: Created connect event\r\n",\r
+              pTcp4->ConnectToken.CompletionToken.Event ));\r
+\r
+    //\r
+    //  Open the port protocol\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    ChildHandle,\r
+                    &gEfiTcp4ProtocolGuid,\r
+                    (VOID **) &pTcp4->pProtocol,\r
+                    pLayer->ImageHandle,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to open gEfiTcp4ProtocolGuid on controller 0x%08x\r\n",\r
+                pTcp4->Handle ));\r
+      pSocket->errno = EEXIST;\r
+      break;\r
+    }\r
+    DEBUG (( DebugFlags,\r
+              "0x%08x: gEfiTcp4ProtocolGuid opened on controller 0x%08x\r\n",\r
+              pTcp4->pProtocol,\r
+              ChildHandle ));\r
+\r
+    //\r
+    //  Set the port address\r
+    //\r
+    pTcp4->Handle = ChildHandle;\r
+    pAccessPoint = &pPort->Context.Tcp4.ConfigData.AccessPoint;\r
+    pAccessPoint->StationPort = PortNumber;\r
+    if (( 0 == pIpAddress[0])\r
+      && ( 0 == pIpAddress[1])\r
+      && ( 0 == pIpAddress[2])\r
+      && ( 0 == pIpAddress[3])) {\r
+      pAccessPoint->UseDefaultAddress = TRUE;\r
+    }\r
+    else {\r
+      pAccessPoint->StationAddress.Addr[0] = pIpAddress[0];\r
+      pAccessPoint->StationAddress.Addr[1] = pIpAddress[1];\r
+      pAccessPoint->StationAddress.Addr[2] = pIpAddress[2];\r
+      pAccessPoint->StationAddress.Addr[3] = pIpAddress[3];\r
+      pAccessPoint->SubnetMask.Addr[0] = 0xff;\r
+      pAccessPoint->SubnetMask.Addr[1] = 0xff;\r
+      pAccessPoint->SubnetMask.Addr[2] = 0xff;\r
+      pAccessPoint->SubnetMask.Addr[3] = 0xff;\r
+    }\r
+    pAccessPoint->ActiveFlag = FALSE;\r
+    pTcp4->ConfigData.TimeToLive = 255;\r
+\r
+    //\r
+    //  Verify the socket layer synchronization\r
+    //\r
+    VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+    //\r
+    //  Add this port to the socket\r
+    //\r
+    pPort->pLinkSocket = pSocket->pPortList;\r
+    pSocket->pPortList = pPort;\r
+    DEBUG (( DebugFlags,\r
+              "0x%08x: Socket adding port: 0x%08x\r\n",\r
+              pSocket,\r
+              pPort ));\r
+\r
+    //\r
+    //  Add this port to the service\r
+    //\r
+    pPort->pLinkService = pService->pPortList;\r
+    pService->pPortList = pPort;\r
+\r
+    //\r
+    //  Return the port\r
+    //\r
+    *ppPort = pPort;\r
+    break;\r
+  }\r
+\r
+  //\r
+  //  Clean up after the error if necessary\r
+  //\r
+  if (( EFI_ERROR ( Status )) && ( NULL != pPort )) {\r
+    //\r
+    //  Close the port\r
+    //\r
+    EslTcpPortClose4 ( pPort );\r
+  }\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Close a TCP4 port.\r
+\r
+  This routine releases the resources allocated by\r
+  ::TcpPortAllocate4().\r
+  \r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS     The port is closed\r
+  @retval other           Port close error\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpPortClose4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  UINTN DebugFlags;\r
+  DT_LAYER * pLayer;\r
+  DT_PACKET * pPacket;\r
+  DT_PORT * pPreviousPort;\r
+  DT_SERVICE * pService;\r
+  DT_SOCKET * pSocket;\r
+  EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+  \r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Locate the port in the socket list\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  pLayer = &mEslLayer;\r
+  DebugFlags = pPort->DebugFlags;\r
+  pSocket = pPort->pSocket;\r
+  pPreviousPort = pSocket->pPortList;\r
+  if ( pPreviousPort == pPort ) {\r
+    //\r
+    //  Remove this port from the head of the socket list\r
+    //\r
+    pSocket->pPortList = pPort->pLinkSocket;\r
+  }\r
+  else {\r
+    //\r
+    //  Locate the port in the middle of the socket list\r
+    //\r
+    while (( NULL != pPreviousPort )\r
+      && ( pPreviousPort->pLinkSocket != pPort )) {\r
+      pPreviousPort = pPreviousPort->pLinkSocket;\r
+    }\r
+    if ( NULL != pPreviousPort ) {\r
+      //\r
+      //  Remove the port from the middle of the socket list\r
+      //\r
+      pPreviousPort->pLinkSocket = pPort->pLinkSocket;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Locate the port in the service list\r
+  //\r
+  pService = pPort->pService;\r
+  pPreviousPort = pService->pPortList;\r
+  if ( pPreviousPort == pPort ) {\r
+    //\r
+    //  Remove this port from the head of the service list\r
+    //\r
+    pService->pPortList = pPort->pLinkService;\r
+  }\r
+  else {\r
+    //\r
+    //  Locate the port in the middle of the service list\r
+    //\r
+    while (( NULL != pPreviousPort )\r
+      && ( pPreviousPort->pLinkService != pPort )) {\r
+      pPreviousPort = pPreviousPort->pLinkService;\r
+    }\r
+    if ( NULL != pPreviousPort ) {\r
+      //\r
+      //  Remove the port from the middle of the service list\r
+      //\r
+      pPreviousPort->pLinkService = pPort->pLinkService;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Empty the urgent receive queue\r
+  //\r
+  pTcp4 = &pPort->Context.Tcp4;\r
+  while ( NULL != pSocket->pRxOobPacketListHead ) {\r
+    pPacket = pSocket->pRxOobPacketListHead;\r
+    pSocket->pRxOobPacketListHead = pPacket->pNext;\r
+    pSocket->RxOobBytes -= pPacket->Op.Tcp4Rx.ValidBytes;\r
+    EslSocketPacketFree ( pPacket, DEBUG_RX );\r
+  }\r
+  pSocket->pRxOobPacketListTail = NULL;\r
+  ASSERT ( 0 == pSocket->RxOobBytes );\r
+\r
+  //\r
+  //  Empty the receive queue\r
+  //\r
+  while ( NULL != pSocket->pRxPacketListHead ) {\r
+    pPacket = pSocket->pRxPacketListHead;\r
+    pSocket->pRxPacketListHead = pPacket->pNext;\r
+    pSocket->RxBytes -= pPacket->Op.Tcp4Rx.ValidBytes;\r
+    EslSocketPacketFree ( pPacket, DEBUG_RX );\r
+  }\r
+  pSocket->pRxPacketListTail = NULL;\r
+  ASSERT ( 0 == pSocket->RxBytes );\r
+\r
+  //\r
+  //  Empty the receive free queue\r
+  //\r
+  while ( NULL != pSocket->pRxFree ) {\r
+    pPacket = pSocket->pRxFree;\r
+    pSocket->pRxFree = pPacket->pNext;\r
+    EslSocketPacketFree ( pPacket, DEBUG_RX );\r
+  }\r
+\r
+  //\r
+  //  Done with the connect event\r
+  //\r
+  if ( NULL != pTcp4->ConnectToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( pTcp4->ConnectToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Closed connect event\r\n",\r
+                pTcp4->ConnectToken.CompletionToken.Event ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close the connect event, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the close event\r
+  //\r
+  if ( NULL != pTcp4->CloseToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( pTcp4->CloseToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Closed close event\r\n",\r
+                pTcp4->CloseToken.CompletionToken.Event ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close the close event, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the listen completion event\r
+  //\r
+  if ( NULL != pTcp4->ListenToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( pTcp4->ListenToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Closed listen completion event\r\n",\r
+                pTcp4->ListenToken.CompletionToken.Event ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close the listen completion event, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the receive event\r
+  //\r
+  if ( NULL != pTcp4->RxToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( pTcp4->RxToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Closed receive event\r\n",\r
+                pTcp4->RxToken.CompletionToken.Event ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close the receive event, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the normal transmit event\r
+  //\r
+  if ( NULL != pTcp4->TxToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( pTcp4->TxToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Closed normal transmit event\r\n",\r
+                pTcp4->TxToken.CompletionToken.Event ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close the normal transmit event, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the urgent transmit event\r
+  //\r
+  if ( NULL != pTcp4->TxOobToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( pTcp4->TxOobToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Closed urgent transmit event\r\n",\r
+                pTcp4->TxOobToken.CompletionToken.Event ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close the urgent transmit event, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the TCP protocol\r
+  //\r
+  pTcp4Service = pService->pInterface;\r
+  if ( NULL != pTcp4->pProtocol ) {\r
+    Status = gBS->CloseProtocol ( pTcp4->Handle,\r
+                                  &gEfiTcp4ProtocolGuid,\r
+                                  pLayer->ImageHandle,\r
+                                  NULL );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags,\r
+                "0x%08x: gEfiTcp4ProtocolGuid closed on controller 0x%08x\r\n",\r
+                pTcp4->pProtocol,\r
+                pTcp4->Handle ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close gEfiTcp4ProtocolGuid opened on controller 0x%08x, Status: %r\r\n",\r
+                pTcp4->Handle,\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the TCP port\r
+  //\r
+  if ( NULL != pTcp4->Handle ) {\r
+    Status = pTcp4Service->DestroyChild ( pTcp4Service,\r
+                                          pTcp4->Handle );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Tcp4 port handle destroyed\r\n",\r
+                pTcp4->Handle ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,\r
+                "ERROR - Failed to destroy the Tcp4 port handle, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Release the port structure\r
+  //\r
+  Status = gBS->FreePool ( pPort );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    DEBUG (( DebugFlags | DEBUG_POOL,\r
+              "0x%08x: Free pPort, %d bytes\r\n",\r
+              pPort,\r
+              sizeof ( *pPort )));\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,\r
+              "ERROR - Failed to free pPort: 0x%08x, Status: %r\r\n",\r
+              pPort,\r
+              Status ));\r
+    ASSERT ( EFI_SUCCESS == Status );\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Process the port close completion\r
+\r
+  @param  Event         The close completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpPortCloseComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Update the port state\r
+  //\r
+  pPort->State = PORT_STATE_CLOSE_DONE;\r
+\r
+  //\r
+  //  Release the resources once the receive operation completes\r
+  //\r
+  Status = EslTcpPortCloseRxDone4 ( pPort );\r
+  DBG_EXIT_STATUS ( Status );\r
+}\r
+\r
+\r
+/**\r
+  Start the close operation on a TCP4 port, state 1.\r
+\r
+  Closing a port goes through the following states:\r
+  1. Port close starting - Mark the port as closing and wait for transmission to complete\r
+  2. Port TX close done - Transmissions complete, close the port and abort the receives\r
+  3. Port RX close done - Receive operations complete, close the port\r
+  4. Port closed - Release the port resources\r
+  \r
+  @param [in] pPort       Address of the port structure.\r
+  @param [in] bCloseNow   Set TRUE to abort active transfers\r
+  @param [in] DebugFlags  Flags for debug messages\r
+\r
+  @retval EFI_SUCCESS         The port is closed, not normally returned\r
+  @retval EFI_NOT_READY       The port has started the closing process\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpPortCloseStart4 (\r
+  IN DT_PORT * pPort,\r
+  IN BOOLEAN bCloseNow,\r
+  IN UINTN DebugFlags\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Mark the port as closing\r
+  //\r
+  Status = EFI_ALREADY_STARTED;\r
+  pSocket = pPort->pSocket;\r
+  pSocket->errno = EALREADY;\r
+  if ( PORT_STATE_CLOSE_STARTED > pPort->State ) {\r
+\r
+    //\r
+    //  Update the port state\r
+    //\r
+    pPort->State = PORT_STATE_CLOSE_STARTED;\r
+    DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+              "0x%08x: Port Close State: PORT_STATE_CLOSE_STARTED\r\n",\r
+              pPort ));\r
+    pPort->bCloseNow = bCloseNow;\r
+    pPort->DebugFlags = DebugFlags;\r
+\r
+    //\r
+    //  Determine if transmits are complete\r
+    //\r
+    Status = EslTcpPortCloseTxDone4 ( pPort );\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Port close state 3\r
+\r
+  Continue the close operation after the receive is complete.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS         The port is closed\r
+  @retval EFI_NOT_READY       The port is still closing\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpPortCloseRxDone4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  PORT_STATE PortState;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Verify that the port is closing\r
+  //\r
+  Status = EFI_ALREADY_STARTED;\r
+  PortState = pPort->State;\r
+  if (( PORT_STATE_CLOSE_TX_DONE == PortState )\r
+    || ( PORT_STATE_CLOSE_DONE == PortState )) {\r
+    //\r
+    //  Determine if the receive operation is pending\r
+    //\r
+    Status = EFI_NOT_READY;\r
+    pTcp4 = &pPort->Context.Tcp4;\r
+    if ( NULL == pTcp4->pReceivePending ) {\r
+      //\r
+      //  The receive operation is complete\r
+      //  Update the port state\r
+      //\r
+      pPort->State = PORT_STATE_CLOSE_RX_DONE;\r
+      DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                "0x%08x: Port Close State: PORT_STATE_CLOSE_RX_DONE\r\n",\r
+                pPort ));\r
+\r
+      //\r
+      //  Determine if the close operation has completed\r
+      //\r
+      if ( PORT_STATE_CLOSE_DONE == PortState ) {\r
+        //\r
+        //  The close operation has completed\r
+        //  Release the port resources\r
+        //\r
+        Status = EslTcpPortClose4 ( pPort );\r
+      }\r
+      else\r
+      {\r
+        DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                  "0x%08x: Port Close: Close operation still pending!\r\n",\r
+                  pPort ));\r
+      }\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                "0x%08x: Port Close: Receive still pending!\r\n",\r
+                pPort ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Port close state 2\r
+\r
+  Continue the close operation after the transmission is complete.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS         The port is closed, not normally returned\r
+  @retval EFI_NOT_READY       The port is still closing\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslTcpPortCloseTxDone4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  All transmissions are complete or must be stopped\r
+  //  Mark the port as TX complete\r
+  //\r
+  Status = EFI_ALREADY_STARTED;\r
+  if ( PORT_STATE_CLOSE_STARTED == pPort->State ) {\r
+    //\r
+    //  Verify that the transmissions are complete\r
+    //\r
+    pSocket = pPort->pSocket;\r
+    if ( pPort->bCloseNow\r
+         || ( EFI_SUCCESS != pSocket->TxError )\r
+         || (( 0 == pSocket->TxOobBytes )\r
+                && ( 0 == pSocket->TxBytes ))) {\r
+      //\r
+      //  Start the close operation on the port\r
+      //\r
+      pTcp4 = &pPort->Context.Tcp4;\r
+      pTcp4->CloseToken.AbortOnClose = FALSE;\r
+      pTcp4Protocol = pTcp4->pProtocol;\r
+      if ( !pTcp4->bConfigured ) {\r
+        //\r
+        //  Skip the close operation since the port is not\r
+        //  configured\r
+        //\r
+        //  Update the port state\r
+        //\r
+        pPort->State = PORT_STATE_CLOSE_DONE;\r
+        DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                  "0x%08x: Port Close State: PORT_STATE_CLOSE_DONE\r\n",\r
+                  pPort ));\r
+        Status = EFI_SUCCESS;\r
+      }\r
+      else {\r
+        //\r
+        //  Close the configured port\r
+        //\r
+        Status = pTcp4Protocol->Close ( pTcp4Protocol,\r
+                                        &pTcp4->CloseToken );\r
+        if ( !EFI_ERROR ( Status )) {\r
+          DEBUG (( pPort->DebugFlags | DEBUG_CLOSE | DEBUG_INFO,\r
+                    "0x%08x: Port close started\r\n",\r
+                    pPort ));\r
+\r
+          //\r
+          //  Update the port state\r
+          //\r
+          pPort->State = PORT_STATE_CLOSE_TX_DONE;\r
+          DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                    "0x%08x: Port Close State: PORT_STATE_CLOSE_TX_DONE\r\n",\r
+                    pPort ));\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_ERROR | pPort->DebugFlags | DEBUG_CLOSE | DEBUG_INFO,\r
+                   "ERROR - Close failed on port 0x%08x, Status: %r\r\n",\r
+                   pPort,\r
+                   Status ));\r
+          ASSERT ( EFI_SUCCESS == Status );\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Determine if the receive operation is pending\r
+      //\r
+      if ( !EFI_ERROR ( Status )) {\r
+        Status = EslTcpPortCloseRxDone4 ( pPort );\r
+      }\r
+    }\r
+    else {\r
+      //\r
+      //  Transmissions are still active, exit\r
+      //\r
+      DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                "0x%08x: Port Close: Transmits are still pending!\r\n",\r
+                pPort ));\r
+      Status = EFI_NOT_READY;\r
+      pSocket->errno = EAGAIN;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Receive data from a network connection.\r
+\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @param [in] Flags           Message control flags\r
+  \r
+  @param [in] BufferLength    Length of the the buffer\r
+  \r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+  \r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpReceive4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN INT32 Flags,\r
+  IN size_t BufferLength,\r
+  IN UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  )\r
+{\r
+  socklen_t AddressLength;\r
+  size_t BytesToCopy;\r
+  in_addr_t IpAddress;\r
+  size_t LengthInBytes;\r
+  DT_PACKET * pPacket;\r
+  DT_PORT * pPort;\r
+  DT_PACKET ** ppQueueHead;\r
+  DT_PACKET ** ppQueueTail;\r
+  struct sockaddr_in * pRemoteAddress;\r
+  size_t * pRxDataBytes;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  struct sockaddr_in RemoteAddress;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+  pSocket->errno = ENOTCONN;\r
+\r
+  //\r
+  //  Verify that the socket is connected\r
+  //\r
+  if (( SOCKET_STATE_CONNECTED == pSocket->State )\r
+    || ( PORT_STATE_RX_ERROR == pSocket->State )) {\r
+    //\r
+    //  Locate the port\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    if ( NULL != pPort ) {\r
+      //\r
+      //  Determine the queue head\r
+      //\r
+      pTcp4 = &pPort->Context.Tcp4;\r
+      if ( 0 != ( Flags & MSG_OOB )) {\r
+        ppQueueHead = &pSocket->pRxOobPacketListHead;\r
+        ppQueueTail = &pSocket->pRxOobPacketListTail;\r
+        pRxDataBytes = &pSocket->RxOobBytes;\r
+      }\r
+      else {\r
+        ppQueueHead = &pSocket->pRxPacketListHead;\r
+        ppQueueTail = &pSocket->pRxPacketListTail;\r
+        pRxDataBytes = &pSocket->RxBytes;\r
+      }\r
+\r
+      //\r
+      //  Determine if there is any data on the queue\r
+      //\r
+      pPacket = *ppQueueHead;\r
+      if ( NULL != pPacket ) {\r
+        //\r
+        //  Validate the return address parameters\r
+        //\r
+        if (( NULL == pAddress ) || ( NULL != pAddressLength )) {\r
+          //\r
+          //  Return the remote system address if requested\r
+          //\r
+          if ( NULL != pAddress ) {\r
+            //\r
+            //  Build the remote address\r
+            //\r
+            ZeroMem ( &RemoteAddress, sizeof ( RemoteAddress ));\r
+            RemoteAddress.sin_len = sizeof ( RemoteAddress );\r
+            RemoteAddress.sin_family = AF_INET;\r
+            IpAddress = pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3];\r
+            IpAddress <<= 8;\r
+            IpAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2];\r
+            IpAddress <<= 8;\r
+            IpAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1];\r
+            IpAddress <<= 8;\r
+            IpAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0];\r
+            RemoteAddress.sin_addr.s_addr = IpAddress;\r
+            RemoteAddress.sin_port = SwapBytes16 ( pTcp4->ConfigData.AccessPoint.RemotePort );\r
+\r
+            //\r
+            //  Copy the address\r
+            //\r
+            pRemoteAddress = (struct sockaddr_in *)pAddress;\r
+            AddressLength = sizeof ( *pRemoteAddress );\r
+            if ( AddressLength > *pAddressLength ) {\r
+              AddressLength = *pAddressLength;\r
+            }\r
+            CopyMem ( pRemoteAddress,\r
+                      &RemoteAddress,\r
+                      AddressLength );\r
+\r
+            //\r
+            //  Update the address length\r
+            //\r
+            *pAddressLength = AddressLength;\r
+          }\r
+\r
+          //\r
+          //  Copy the received data\r
+          //\r
+          LengthInBytes = 0;\r
+          do {\r
+            //\r
+            //  Determine the amount of received data\r
+            //\r
+            BytesToCopy = pPacket->Op.Tcp4Rx.ValidBytes;\r
+            if (( BufferLength - LengthInBytes ) < BytesToCopy ) {\r
+              BytesToCopy = BufferLength - LengthInBytes;\r
+            }\r
+            LengthInBytes += BytesToCopy;\r
+\r
+            //\r
+            //  Move the data into the buffer\r
+            //\r
+            DEBUG (( DEBUG_RX,\r
+                      "0x%08x: Port copy packet 0x%08x data into 0x%08x, 0x%08x bytes\r\n",\r
+                      pPort,\r
+                      pPacket,\r
+                      pBuffer,\r
+                      BytesToCopy ));\r
+            CopyMem ( pBuffer, pPacket->Op.Tcp4Rx.pBuffer, BytesToCopy );\r
+\r
+            //\r
+            //  Determine if the data is being read\r
+            //\r
+            if ( 0 == ( Flags & MSG_PEEK )) {\r
+              //\r
+              //  Account for the bytes consumed\r
+              //\r
+              pPacket->Op.Tcp4Rx.pBuffer += BytesToCopy;\r
+              pPacket->Op.Tcp4Rx.ValidBytes -= BytesToCopy;\r
+              *pRxDataBytes -= BytesToCopy;\r
+              DEBUG (( DEBUG_RX,\r
+                        "0x%08x: Port account for 0x%08x bytes\r\n",\r
+                        pPort,\r
+                        BytesToCopy ));\r
+\r
+              //\r
+              //  Determine if the entire packet was consumed\r
+              //\r
+              if (( 0 == pPacket->Op.Tcp4Rx.ValidBytes )\r
+                || ( SOCK_STREAM != pSocket->Type )) {\r
+                //\r
+                //  All done with this packet\r
+                //  Account for any discarded data\r
+                //\r
+                *pRxDataBytes -= pPacket->Op.Tcp4Rx.ValidBytes;\r
+                if ( 0 != pPacket->Op.Tcp4Rx.ValidBytes ) {\r
+                  DEBUG (( DEBUG_RX,\r
+                            "0x%08x: Port, packet read, skipping over 0x%08x bytes\r\n",\r
+                            pPort,\r
+                            pPacket->Op.Tcp4Rx.ValidBytes ));\r
+                }\r
+\r
+                //\r
+                //  Remove this packet from the queue\r
+                //\r
+                *ppQueueHead = pPacket->pNext;\r
+                if ( NULL == *ppQueueHead ) {\r
+                  *ppQueueTail = NULL;\r
+                }\r
+\r
+                //\r
+                //  Move the packet to the free queue\r
+                //\r
+                pPacket->pNext = pSocket->pRxFree;\r
+                pSocket->pRxFree = pPacket;\r
+                DEBUG (( DEBUG_RX,\r
+                          "0x%08x: Port freeing packet 0x%08x\r\n",\r
+                          pPort,\r
+                          pPacket ));\r
+\r
+                //\r
+                //  Restart this receive operation if necessary\r
+                //\r
+                if (( NULL == pTcp4->pReceivePending )\r
+                  && ( MAX_RX_DATA > pSocket->RxBytes )) {\r
+                    EslTcpRxStart4 ( pPort );\r
+                }\r
+              }\r
+            }\r
+\r
+            //\r
+            //  Get the next packet\r
+            //\r
+            pPacket = *ppQueueHead;\r
+          } while (( SOCK_STREAM == pSocket->Type )\r
+                && ( NULL != pPacket )\r
+                && ( 0 == ( Flags & MSG_PEEK ))\r
+                && ( BufferLength > LengthInBytes ));\r
+\r
+          //\r
+          //  Return the data length\r
+          //\r
+          *pDataLength = LengthInBytes;\r
+\r
+          //\r
+          //  Successful operation\r
+          //\r
+          Status = EFI_SUCCESS;\r
+          pSocket->errno = 0;\r
+        }\r
+        else {\r
+          //\r
+          //  Bad return address pointer and length\r
+          //\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EINVAL;\r
+        }\r
+      }\r
+      else {\r
+        //\r
+        //  The queue is empty\r
+        //  Determine if it is time to return the receive error\r
+        //\r
+        if ( EFI_ERROR ( pSocket->RxError )\r
+          && ( NULL == pSocket->pRxPacketListHead )\r
+          && ( NULL == pSocket->pRxOobPacketListHead )) {\r
+          Status = pSocket->RxError;\r
+          switch ( Status ) {\r
+          default:\r
+            pSocket->errno = EIO;\r
+            break;\r
+          \r
+          case EFI_CONNECTION_FIN:\r
+            pSocket->errno = ESHUTDOWN;\r
+            break;\r
+\r
+          case EFI_CONNECTION_REFUSED:\r
+            pSocket->errno = ECONNREFUSED;\r
+            break;\r
+\r
+          case EFI_CONNECTION_RESET:\r
+            pSocket->errno = ECONNRESET;\r
+            break;\r
+\r
+          case EFI_HOST_UNREACHABLE:\r
+            pSocket->errno = EHOSTUNREACH;\r
+            break;\r
+          \r
+          case EFI_NETWORK_UNREACHABLE:\r
+            pSocket->errno = ENETUNREACH;\r
+            break;\r
+          \r
+          case EFI_PORT_UNREACHABLE:\r
+            pSocket->errno = EPROTONOSUPPORT;\r
+            break;\r
+          \r
+          case EFI_PROTOCOL_UNREACHABLE:\r
+            pSocket->errno = ENOPROTOOPT;\r
+            break;\r
+          }\r
+          pSocket->RxError = EFI_SUCCESS;\r
+        }\r
+        else {\r
+          Status = EFI_NOT_READY;\r
+          pSocket->errno = EAGAIN;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Cancel the receive operations\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @retval EFI_SUCCESS - The cancel was successful\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpRxCancel4 (\r
+  IN DT_SOCKET * pSocket\r
+  )\r
+{\r
+  DT_PACKET * pPacket;\r
+  DT_PORT * pPort;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_NOT_FOUND;\r
+\r
+  //\r
+  //  Locate the port\r
+  //\r
+  pPort = pSocket->pPortList;\r
+  if ( NULL != pPort ) {\r
+    //\r
+    //  Determine if a receive is pending\r
+    //\r
+    pTcp4 = &pPort->Context.Tcp4;\r
+    pPacket = pTcp4->pReceivePending;\r
+    if ( NULL != pPacket ) {\r
+      //\r
+      //  Attempt to cancel the receive operation\r
+      //\r
+      pTcp4Protocol = pTcp4->pProtocol;\r
+      Status = pTcp4Protocol->Cancel ( pTcp4Protocol,\r
+                                       &pTcp4->RxToken.CompletionToken );\r
+      if ( EFI_NOT_FOUND == Status ) {\r
+        //\r
+        //  The receive is complete\r
+        //\r
+        Status = EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Process the receive completion\r
+\r
+  Buffer the data that was just received.\r
+\r
+  @param  Event         The receive completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpRxComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  BOOLEAN bUrgent;\r
+  size_t LengthInBytes;\r
+  DT_PACKET * pPacket;\r
+  DT_PACKET * pPrevious;\r
+  DT_SOCKET * pSocket;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Mark this receive complete\r
+  //\r
+  pTcp4 = &pPort->Context.Tcp4;\r
+  pPacket = pTcp4->pReceivePending;\r
+  pTcp4->pReceivePending = NULL;\r
+\r
+  //\r
+  //  Determine if this receive was successful\r
+  //\r
+  pSocket = pPort->pSocket;\r
+  Status = pTcp4->RxToken.CompletionToken.Status;\r
+  if (( !EFI_ERROR ( Status )) && ( !pSocket->bRxDisable )) {\r
+    //\r
+    //  Set the buffer size and address\r
+    //\r
+    pPacket->Op.Tcp4Rx.pBuffer = pPacket->Op.Tcp4Rx.RxData.FragmentTable[0].FragmentBuffer;\r
+    LengthInBytes = pPacket->Op.Tcp4Rx.RxData.DataLength;\r
+    pPacket->Op.Tcp4Rx.ValidBytes = LengthInBytes;\r
+    pPacket->pNext = NULL;\r
+\r
+    //\r
+    //  Queue this packet\r
+    //\r
+    bUrgent = pPacket->Op.Tcp4Rx.RxData.UrgentFlag;\r
+    if ( bUrgent ) {\r
+      //\r
+      //  Add packet to the urgent list\r
+      //\r
+      pPrevious = pSocket->pRxOobPacketListTail;\r
+      if ( NULL == pPrevious ) {\r
+        pSocket->pRxOobPacketListHead = pPacket;\r
+      }\r
+      else {\r
+        pPrevious->pNext = pPacket;\r
+      }\r
+      pSocket->pRxOobPacketListTail = pPacket;\r
+\r
+      //\r
+      //  Account for the urgent data\r
+      //\r
+      pSocket->RxOobBytes += LengthInBytes;\r
+    }\r
+    else {\r
+      //\r
+      //  Add packet to the normal list\r
+      //\r
+      pPrevious = pSocket->pRxPacketListTail;\r
+      if ( NULL == pPrevious ) {\r
+        pSocket->pRxPacketListHead = pPacket;\r
+      }\r
+      else {\r
+        pPrevious->pNext = pPacket;\r
+      }\r
+      pSocket->pRxPacketListTail = pPacket;\r
+\r
+      //\r
+      //  Account for the normal data\r
+      //\r
+      pSocket->RxBytes += LengthInBytes;\r
+    }\r
+\r
+    //\r
+    //  Log the received data\r
+    //\r
+    DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+              "0x%08x: Packet queued on port 0x%08x with 0x%08x bytes of %s data\r\n",\r
+              pPacket,\r
+              pPort,\r
+              LengthInBytes,\r
+              bUrgent ? L"urgent" : L"normal" ));\r
+\r
+    //\r
+    //  Attempt to restart this receive operation\r
+    //\r
+    if ( pSocket->MaxRxBuf > pSocket->RxBytes ) {\r
+      EslTcpRxStart4 ( pPort );\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_RX,\r
+                "0x%08x: Port RX suspended, 0x%08x bytes queued\r\n",\r
+                pPort,\r
+                pSocket->RxBytes ));\r
+    }\r
+  }\r
+  else\r
+  {\r
+    DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+              "ERROR - Receiving packet 0x%08x, on port 0x%08x, Status:%r\r\n",\r
+              pPacket,\r
+              pPort,\r
+              Status ));\r
+\r
+    //\r
+    //  Receive error, free the packet save the error\r
+    //\r
+    EslSocketPacketFree ( pPacket, DEBUG_RX );\r
+    if ( !EFI_ERROR ( pSocket->RxError )) {\r
+      pSocket->RxError = Status;\r
+    }\r
+\r
+    //\r
+    //  Update the port state\r
+    //\r
+    if ( PORT_STATE_CLOSE_STARTED <= pPort->State ) {\r
+      EslTcpPortCloseRxDone4 ( pPort );\r
+    }\r
+    else {\r
+      if ( EFI_ERROR ( Status )) {\r
+        pPort->State = PORT_STATE_RX_ERROR;\r
+      }\r
+    }\r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Start a receive operation\r
+\r
+  @param [in] pPort       Address of the DT_PORT structure.\r
+\r
+ **/\r
+VOID\r
+EslTcpRxStart4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  size_t LengthInBytes;\r
+  DT_PACKET * pPacket;\r
+  DT_SOCKET * pSocket;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Determine if a receive is already pending\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  pPacket = NULL;\r
+  pSocket = pPort->pSocket;\r
+  pTcp4 = &pPort->Context.Tcp4;\r
+  if ( !EFI_ERROR ( pPort->pSocket->RxError )) {\r
+    if (( NULL == pTcp4->pReceivePending )\r
+      && ( PORT_STATE_CLOSE_STARTED > pPort->State )) {\r
+      //\r
+      //  Determine if there are any free packets\r
+      //\r
+      pPacket = pSocket->pRxFree;\r
+      LengthInBytes = sizeof ( pPacket->Op.Tcp4Rx.Buffer );\r
+      if ( NULL != pPacket ) {\r
+        //\r
+        //  Remove this packet from the free list\r
+        //\r
+        pSocket->pRxFree = pPacket->pNext;\r
+        DEBUG (( DEBUG_RX,\r
+                  "0x%08x: Port removed packet 0x%08x from free list\r\n",\r
+                  pPort,\r
+                  pPacket ));\r
+      }\r
+      else {\r
+        //\r
+        //  Allocate a packet structure\r
+        //\r
+        Status = EslSocketPacketAllocate ( &pPacket,\r
+                                           sizeof ( pPacket->Op.Tcp4Rx ),\r
+                                           DEBUG_RX );\r
+        if ( EFI_ERROR ( Status )) {\r
+          pPacket = NULL;\r
+          DEBUG (( DEBUG_ERROR | DEBUG_RX,\r
+                    "0x%08x: Port failed to allocate RX packet, Status: %r\r\n",\r
+                    pPort,\r
+                    Status ));\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Determine if a packet is available\r
+      //\r
+      if ( NULL != pPacket ) {\r
+        //\r
+        //  Initialize the buffer for receive\r
+        //\r
+        pTcp4->RxToken.Packet.RxData = &pPacket->Op.Tcp4Rx.RxData;\r
+        pPacket->Op.Tcp4Rx.RxData.DataLength = (UINT32) LengthInBytes;\r
+        pPacket->Op.Tcp4Rx.RxData.FragmentCount = 1;\r
+        pPacket->Op.Tcp4Rx.RxData.FragmentTable [0].FragmentLength = (UINT32) LengthInBytes;\r
+        pPacket->Op.Tcp4Rx.RxData.FragmentTable [0].FragmentBuffer = &pPacket->Op.Tcp4Rx.Buffer [0];\r
+        pTcp4->pReceivePending = pPacket;\r
+\r
+        //\r
+        //  Start the receive on the packet\r
+        //\r
+        pTcp4Protocol = pTcp4->pProtocol;\r
+        Status = pTcp4Protocol->Receive ( pTcp4Protocol,\r
+                                          &pTcp4->RxToken );\r
+        if ( !EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+                    "0x%08x: Packet receive pending on port 0x%08x\r\n",\r
+                    pPacket,\r
+                    pPort ));\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+                    "ERROR - Failed to post a receive on port 0x%08x, Status: %r\r\n",\r
+                    pPort,\r
+                    Status ));\r
+          pTcp4->pReceivePending = NULL;\r
+          if ( !EFI_ERROR ( pSocket->RxError )) {\r
+            //\r
+            //  Save the error status\r
+            //\r
+            pSocket->RxError = Status;\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Shutdown the TCP4 service.\r
+\r
+  This routine undoes the work performed by ::TcpInitialize4.\r
+\r
+  @param [in] pService        DT_SERVICE structure address\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EslTcpShutdown4 (\r
+  IN DT_SERVICE * pService\r
+  )\r
+{\r
+  DT_LAYER * pLayer;\r
+  DT_PORT * pPort;\r
+  DT_SERVICE * pPreviousService;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Walk the list of ports\r
+  //\r
+  do {\r
+    pPort = pService->pPortList;\r
+    if ( NULL != pPort ) {\r
+      //\r
+      //  Remove the port from the port list\r
+      //\r
+      pService->pPortList = pPort->pLinkService;\r
+\r
+      //\r
+      //  Close the port\r
+      // TODO: Fix this\r
+      //\r
+//      pPort->pfnClosePort ( pPort, DEBUG_LISTEN | DEBUG_CONNECTION );\r
+    }\r
+  } while ( NULL != pPort );\r
+\r
+  //\r
+  //  Remove the service from the service list\r
+  //\r
+  pLayer = &mEslLayer;\r
+  pPreviousService = pLayer->pTcp4List;\r
+  if ( pService == pPreviousService ) {\r
+    //\r
+    //  Remove the service from the beginning of the list\r
+    //\r
+    pLayer->pTcp4List = pService->pNext;\r
+  }\r
+  else {\r
+    //\r
+    //  Remove the service from the middle of the list\r
+    //\r
+    while ( NULL != pPreviousService ) {\r
+      if ( pService == pPreviousService->pNext ) {\r
+        pPreviousService->pNext = pService->pNext;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Determine if the socket is configured.\r
+\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @retval EFI_SUCCESS - The port is connected\r
+  @retval EFI_NOT_STARTED - The port is not connected\r
+\r
+ **/\r
+ EFI_STATUS\r
+ EslTcpSocketIsConfigured4 (\r
+  IN DT_SOCKET * pSocket\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Determine the socket configuration status\r
+  //\r
+  Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
+\r
+  //\r
+  //  Return the port connected state.\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Buffer data for transmission over a network connection.\r
+\r
+  This routine is called by the socket layer API to buffer\r
+  data for transmission.  When necessary, this routine will\r
+  start the transmit engine that performs the data transmission\r
+  on the network connection.\r
+\r
+  The transmit engine uses two queues, one for urgent (out-of-band)\r
+  data and the other for normal data.  The urgent data is provided\r
+  to TCP as soon as it is available, allowing the TCP layer to\r
+  schedule transmission of the urgent data between packets of normal\r
+  data.\r
+\r
+  Transmission errors are returned during the next transmission or\r
+  during the close operation.  Only buffering errors are returned\r
+  during the current transmission attempt.\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @param [in] Flags           Message control flags\r
+  \r
+  @param [in] BufferLength    Length of the the buffer\r
+  \r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+  \r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully buffered\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcpTxBuffer4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN int Flags,\r
+  IN size_t BufferLength,\r
+  IN CONST UINT8 * pBuffer,\r
+  OUT size_t * pDataLength\r
+  )\r
+{\r
+  BOOLEAN bUrgent;\r
+  DT_PACKET * pPacket;\r
+  DT_PACKET * pPreviousPacket;\r
+  DT_PACKET ** ppPacket;\r
+  DT_PACKET ** ppQueueHead;\r
+  DT_PACKET ** ppQueueTail;\r
+  DT_PORT * pPort;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_TCP4_IO_TOKEN * pToken;\r
+  size_t * pTxBytes;\r
+  EFI_TCP4_TRANSMIT_DATA * pTxData;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+  pSocket->errno = ENOTCONN;\r
+  * pDataLength = 0;\r
+\r
+  //\r
+  //  Verify that the socket is connected\r
+  //\r
+  if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
+    //\r
+    //  Locate the port\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    if ( NULL != pPort ) {\r
+      //\r
+      //  Determine the queue head\r
+      //\r
+      pTcp4 = &pPort->Context.Tcp4;\r
+      bUrgent = (BOOLEAN)( 0 != ( Flags & MSG_OOB ));\r
+      if ( bUrgent ) {\r
+        ppQueueHead = &pSocket->pTxOobPacketListHead;\r
+        ppQueueTail = &pSocket->pTxOobPacketListTail;\r
+        ppPacket = &pTcp4->pTxOobPacket;\r
+        pToken = &pTcp4->TxOobToken;\r
+        pTxBytes = &pSocket->TxOobBytes;\r
+      }\r
+      else {\r
+        ppQueueHead = &pSocket->pTxPacketListHead;\r
+        ppQueueTail = &pSocket->pTxPacketListTail;\r
+        ppPacket = &pTcp4->pTxPacket;\r
+        pToken = &pTcp4->TxToken;\r
+        pTxBytes = &pSocket->TxBytes;\r
+      }\r
+\r
+      //\r
+      //  Verify that there is enough room to buffer another\r
+      //  transmit operation\r
+      //\r
+      if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
+        //\r
+        //  Attempt to allocate the packet\r
+        //\r
+        Status = EslSocketPacketAllocate ( &pPacket,\r
+                                           sizeof ( pPacket->Op.Tcp4Tx )\r
+                                           - sizeof ( pPacket->Op.Tcp4Tx.Buffer )\r
+                                           + BufferLength,\r
+                                           DEBUG_TX );\r
+        if ( !EFI_ERROR ( Status )) {\r
+          //\r
+          //  Initialize the transmit operation\r
+          //\r
+          pTxData = &pPacket->Op.Tcp4Tx.TxData;\r
+          pTxData->Push = TRUE;\r
+          pTxData->Urgent = bUrgent;\r
+          pTxData->DataLength = (UINT32) BufferLength;\r
+          pTxData->FragmentCount = 1;\r
+          pTxData->FragmentTable[0].FragmentLength = (UINT32) BufferLength;\r
+          pTxData->FragmentTable[0].FragmentBuffer = &pPacket->Op.Tcp4Tx.Buffer[0];\r
+\r
+          //\r
+          //  Copy the data into the buffer\r
+          //\r
+          CopyMem ( &pPacket->Op.Tcp4Tx.Buffer[0],\r
+                    pBuffer,\r
+                    BufferLength );\r
+\r
+          //\r
+          //  Synchronize with the socket layer\r
+          //\r
+          RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+          //\r
+          //  Stop transmission after an error\r
+          //\r
+          if ( !EFI_ERROR ( pSocket->TxError )) {\r
+            //\r
+            //  Display the request\r
+            //\r
+            DEBUG (( DEBUG_TX,\r
+                      "Send %d %s bytes from 0x%08x\r\n",\r
+                      BufferLength,\r
+                      bUrgent ? L"urgent" : L"normal",\r
+                      pBuffer ));\r
+\r
+            //\r
+            //  Queue the data for transmission\r
+            //\r
+            pPacket->pNext = NULL;\r
+            pPreviousPacket = *ppQueueTail;\r
+            if ( NULL == pPreviousPacket ) {\r
+              *ppQueueHead = pPacket;\r
+            }\r
+            else {\r
+              pPreviousPacket->pNext = pPacket;\r
+            }\r
+            *ppQueueTail = pPacket;\r
+            DEBUG (( DEBUG_TX,\r
+                      "0x%08x: Packet on %s transmit list\r\n",\r
+                      pPacket,\r
+                      bUrgent ? L"urgent" : L"normal" ));\r
+\r
+            //\r
+            //  Account for the buffered data\r
+            //\r
+            *pTxBytes += BufferLength;\r
+            *pDataLength = BufferLength;\r
+\r
+            //\r
+            //  Start the transmit engine if it is idle\r
+            //\r
+            if ( NULL == *ppPacket ) {\r
+              EslTcpTxStart4 ( pSocket->pPortList,\r
+                               pToken,\r
+                               ppQueueHead,\r
+                               ppQueueTail,\r
+                               ppPacket );\r
+            }\r
+          }\r
+          else {\r
+            //\r
+            //  Previous transmit error\r
+            //  Stop transmission\r
+            //\r
+            Status = pSocket->TxError;\r
+            pSocket->errno = EIO;\r
+\r
+            //\r
+            //  Free the packet\r
+            //\r
+            EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+          }\r
+\r
+          //\r
+          //  Release the socket layer synchronization\r
+          //\r
+          RESTORE_TPL ( TplPrevious );\r
+        }\r
+        else {\r
+          //\r
+          //  Packet allocation failed\r
+          //\r
+          pSocket->errno = ENOMEM;\r
+        }\r
+      }\r
+      else {\r
+        //\r
+        //  Not enough buffer space available\r
+        //\r
+        pSocket->errno = EAGAIN;\r
+        Status = EFI_NOT_READY;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Process the normal data transmit completion\r
+\r
+  @param  Event         The normal transmit completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpTxComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  UINT32 LengthInBytes;\r
+  DT_PACKET * pCurrentPacket;\r
+  DT_PACKET * pNextPacket;\r
+  DT_PACKET * pPacket;\r
+  DT_SOCKET * pSocket;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+  \r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Locate the active transmit packet\r
+  //\r
+  pSocket = pPort->pSocket;\r
+  pTcp4 = &pPort->Context.Tcp4;\r
+  pPacket = pTcp4->pTxPacket;\r
+  \r
+  //\r
+  //  Mark this packet as complete\r
+  //\r
+  pTcp4->pTxPacket = NULL;\r
+  LengthInBytes = pPacket->Op.Tcp4Tx.TxData.DataLength;\r
+  pSocket->TxBytes -= LengthInBytes;\r
+  \r
+  //\r
+  //  Save any transmit error\r
+  //\r
+  Status = pTcp4->TxToken.CompletionToken.Status;\r
+  if ( EFI_ERROR ( Status )) {\r
+    if ( !EFI_ERROR ( pSocket->TxError )) {\r
+      pSocket->TxError = Status;\r
+    }\r
+    DEBUG (( DEBUG_TX | DEBUG_INFO,\r
+              "ERROR - Transmit failure for packet 0x%08x, Status: %r\r\n",\r
+              pPacket,\r
+              Status ));\r
+\r
+    //\r
+    //  Empty the normal transmit list\r
+    //\r
+    pCurrentPacket = pPacket;\r
+    pNextPacket = pSocket->pTxPacketListHead;\r
+    while ( NULL != pNextPacket ) {\r
+      pPacket = pNextPacket;\r
+      pNextPacket = pPacket->pNext;\r
+      EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+    }\r
+    pSocket->pTxPacketListHead = NULL;\r
+    pSocket->pTxPacketListTail = NULL;\r
+    pPacket = pCurrentPacket;\r
+  }\r
+  else\r
+  {\r
+    DEBUG (( DEBUG_TX | DEBUG_INFO,\r
+              "0x%08x: Packet transmitted %d bytes successfully\r\n",\r
+              pPacket,\r
+              LengthInBytes ));\r
+\r
+    //\r
+    //  Verify the transmit engine is still running\r
+    //\r
+    if ( !pPort->bCloseNow ) {\r
+      //\r
+      //  Start the next packet transmission\r
+      //\r
+      EslTcpTxStart4 ( pPort,\r
+                       &pTcp4->TxToken,\r
+                       &pSocket->pTxPacketListHead,\r
+                       &pSocket->pTxPacketListTail,\r
+                       &pTcp4->pTxPacket );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Release this packet\r
+  //\r
+  EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+\r
+  //\r
+  //  Finish the close operation if necessary\r
+  //\r
+  if ( PORT_STATE_CLOSE_STARTED <= pPort->State ) {\r
+    //\r
+    //  Indicate that the transmit is complete\r
+    //\r
+    EslTcpPortCloseTxDone4 ( pPort );\r
+  }\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Process the urgent data transmit completion\r
+\r
+  @param  Event         The urgent transmit completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslTcpTxOobComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  UINT32 LengthInBytes;\r
+  DT_PACKET * pCurrentPacket;\r
+  DT_PACKET * pNextPacket;\r
+  DT_PACKET * pPacket;\r
+  DT_SOCKET * pSocket;\r
+  DT_TCP4_CONTEXT * pTcp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Locate the active transmit packet\r
+  //\r
+  pSocket = pPort->pSocket;\r
+  pTcp4 = &pPort->Context.Tcp4;\r
+  pPacket = pTcp4->pTxOobPacket;\r
+\r
+  //\r
+  //  Mark this packet as complete\r
+  //\r
+  pTcp4->pTxOobPacket = NULL;\r
+  LengthInBytes = pPacket->Op.Tcp4Tx.TxData.DataLength;\r
+  pSocket->TxOobBytes -= LengthInBytes;\r
+\r
+  //\r
+  //  Save any transmit error\r
+  //\r
+  Status = pTcp4->TxOobToken.CompletionToken.Status;\r
+  if ( EFI_ERROR ( Status )) {\r
+    if ( !EFI_ERROR ( Status )) {\r
+      pSocket->TxError = Status;\r
+    }\r
+    DEBUG (( DEBUG_TX | DEBUG_INFO,\r
+              "ERROR - Transmit failure for urgent packet 0x%08x, Status: %r\r\n",\r
+              pPacket,\r
+              Status ));\r
+\r
+\r
+    //\r
+    //  Empty the OOB transmit list\r
+    //\r
+    pCurrentPacket = pPacket;\r
+    pNextPacket = pSocket->pTxOobPacketListHead;\r
+    while ( NULL != pNextPacket ) {\r
+      pPacket = pNextPacket;\r
+      pNextPacket = pPacket->pNext;\r
+      EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+    }\r
+    pSocket->pTxOobPacketListHead = NULL;\r
+    pSocket->pTxOobPacketListTail = NULL;\r
+    pPacket = pCurrentPacket;\r
+  }\r
+  else\r
+  {\r
+    DEBUG (( DEBUG_TX | DEBUG_INFO,\r
+              "0x%08x: Urgent packet transmitted %d bytes successfully\r\n",\r
+              pPacket,\r
+              LengthInBytes ));\r
+\r
+    //\r
+    //  Verify the transmit engine is still running\r
+    //\r
+    if ( !pPort->bCloseNow ) {\r
+      //\r
+      //  Start the next packet transmission\r
+      //\r
+      EslTcpTxStart4 ( pPort,\r
+                       &pTcp4->TxOobToken,\r
+                       &pSocket->pTxOobPacketListHead,\r
+                       &pSocket->pTxOobPacketListTail,\r
+                       &pTcp4->pTxOobPacket );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Release this packet\r
+  //\r
+  EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+\r
+  //\r
+  //  Finish the close operation if necessary\r
+  //\r
+  if ( PORT_STATE_CLOSE_STARTED <= pPort->State ) {\r
+    //\r
+    //  Indicate that the transmit is complete\r
+    //\r
+    EslTcpPortCloseTxDone4 ( pPort );\r
+  }\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Transmit data using a network connection.\r
+\r
+\r
+  @param [in] pPort           Address of a DT_PORT structure\r
+  @param [in] pToken          Address of either the OOB or normal transmit token\r
+  @param [in] ppQueueHead     Transmit queue head address\r
+  @param [in] ppQueueTail     Transmit queue tail address\r
+  @param [in] ppPacket        Active transmit packet address\r
+\r
+ **/\r
+VOID\r
+EslTcpTxStart4 (\r
+  IN DT_PORT * pPort,\r
+  IN EFI_TCP4_IO_TOKEN * pToken,\r
+  IN DT_PACKET ** ppQueueHead,\r
+  IN DT_PACKET ** ppQueueTail,\r
+  IN DT_PACKET ** ppPacket\r
+  )\r
+{\r
+  DT_PACKET * pNextPacket;\r
+  DT_PACKET * pPacket;\r
+  DT_SOCKET * pSocket;\r
+  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Get the packet from the queue head\r
+  //\r
+  pPacket = *ppQueueHead;\r
+  if ( NULL != pPacket ) {\r
+    //\r
+    //  Remove the packet from the queue\r
+    //\r
+    pNextPacket = pPacket->pNext;\r
+    *ppQueueHead = pNextPacket;\r
+    if ( NULL == pNextPacket ) {\r
+      *ppQueueTail = NULL;\r
+    }\r
+\r
+    //\r
+    //  Set the packet as active\r
+    //\r
+    *ppPacket = pPacket;\r
+\r
+    //\r
+    //  Start the transmit operation\r
+    //\r
+    pTcp4Protocol = pPort->Context.Tcp4.pProtocol;\r
+    pToken->Packet.TxData = &pPacket->Op.Tcp4Tx.TxData;\r
+    Status = pTcp4Protocol->Transmit ( pTcp4Protocol, pToken );\r
+    if ( EFI_ERROR ( Status )) {\r
+      pSocket = pPort->pSocket;\r
+      if ( EFI_SUCCESS == pSocket->TxError ) {\r
+        pSocket->TxError = Status;\r
+      }\r
+    }\r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
diff --git a/StdLib/EfiSocketLib/Udp4.c b/StdLib/EfiSocketLib/Udp4.c
new file mode 100644 (file)
index 0000000..95fc665
--- /dev/null
@@ -0,0 +1,2408 @@
+/** @file\r
+  Implement the UDP4 driver support for the socket layer.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Socket.h"\r
+\r
+\r
+/**\r
+  Bind a name to a socket.\r
+\r
+  The ::UdpBind4 routine connects a name to a UDP4 stack on the local machine.\r
+\r
+  The configure call to the UDP4 driver occurs on the first poll, recv, recvfrom,\r
+  send or sentto call.  Until then, all changes are made in the local UDP context\r
+  structure.\r
+  \r
+  @param [in] pSocket   Address of the socket structure.\r
+\r
+  @param [in] pSockAddr Address of a sockaddr structure that contains the\r
+                        connection point on the local machine.  An IPv4 address\r
+                        of INADDR_ANY specifies that the connection is made to\r
+                        all of the network stacks on the platform.  Specifying a\r
+                        specific IPv4 address restricts the connection to the\r
+                        network stack supporting that address.  Specifying zero\r
+                        for the port causes the network layer to assign a port\r
+                        number from the dynamic range.  Specifying a specific\r
+                        port number causes the network layer to use that port.\r
+\r
+  @param [in] SockAddrLen   Specifies the length in bytes of the sockaddr structure.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdpBind4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength\r
+  )\r
+{\r
+  EFI_HANDLE ChildHandle;\r
+  DT_LAYER * pLayer;\r
+  DT_PORT * pPort;\r
+  DT_SERVICE * pService;\r
+  CONST struct sockaddr_in * pIp4Address;\r
+  EFI_SERVICE_BINDING_PROTOCOL * pUdp4Service;\r
+  EFI_STATUS Status;\r
+  EFI_STATUS TempStatus;\r
+  \r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+  \r
+  //\r
+  //  Assume success\r
+  //\r
+  pSocket->errno = 0;\r
+  Status = EFI_SUCCESS;\r
+  \r
+  //\r
+  //  Validate the address length\r
+  //\r
+  pIp4Address = (CONST struct sockaddr_in *) pSockAddr;\r
+  if ( SockAddrLength >= ( sizeof ( *pIp4Address )\r
+                           - sizeof ( pIp4Address->sin_zero ))) {\r
+\r
+    //\r
+    //  Walk the list of services\r
+    //\r
+    pLayer = &mEslLayer;\r
+    pService = pLayer->pUdp4List;\r
+    while ( NULL != pService ) {\r
+\r
+      //\r
+      //  Create the UDP port\r
+      //\r
+      pUdp4Service = pService->pInterface;\r
+      ChildHandle = NULL;\r
+      Status = pUdp4Service->CreateChild ( pUdp4Service,\r
+                                           &ChildHandle );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
+                  "0x%08x: Udp4 port handle created\r\n",\r
+                  ChildHandle ));\r
+  \r
+        //\r
+        //  Open the port\r
+        //\r
+        Status = EslUdpPortAllocate4 ( pSocket,\r
+                                       pService,\r
+                                       ChildHandle,\r
+                                       (UINT8 *) &pIp4Address->sin_addr.s_addr,\r
+                                       SwapBytes16 ( pIp4Address->sin_port ),\r
+                                       DEBUG_BIND,\r
+                                       &pPort );\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
+                  "ERROR - Failed to open Udp4 port handle, Status: %r\r\n",\r
+                  Status ));\r
+        ChildHandle = NULL;\r
+      }\r
+  \r
+      //\r
+      //  Close the port if necessary\r
+      //\r
+      if (( EFI_ERROR ( Status )) && ( NULL != ChildHandle )) {\r
+        TempStatus = pUdp4Service->DestroyChild ( pUdp4Service,\r
+                                                  ChildHandle );\r
+        if ( !EFI_ERROR ( TempStatus )) {\r
+          DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
+                    "0x%08x: Udp4 port handle destroyed\r\n",\r
+                    ChildHandle ));\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_ERROR | DEBUG_BIND | DEBUG_POOL,\r
+                    "ERROR - Failed to destroy the Udp4 port handle 0x%08x, Status: %r\r\n",\r
+                    ChildHandle,\r
+                    TempStatus ));\r
+          ASSERT ( EFI_SUCCESS == TempStatus );\r
+        }\r
+      }\r
+  \r
+      //\r
+      //  Set the next service\r
+      //\r
+      pService = pService->pNext;\r
+    }\r
+  \r
+    //\r
+    //  Verify that at least one network connection was found\r
+    //\r
+    if ( NULL == pSocket->pPortList ) {\r
+      DEBUG (( DEBUG_BIND | DEBUG_POOL | DEBUG_INIT,\r
+                "Socket address %d.%d.%d.%d (0x%08x) is not available!\r\n",\r
+                ( pIp4Address->sin_addr.s_addr >> 24 ) & 0xff,\r
+                ( pIp4Address->sin_addr.s_addr >> 16 ) & 0xff,\r
+                ( pIp4Address->sin_addr.s_addr >> 8 ) & 0xff,\r
+                pIp4Address->sin_addr.s_addr & 0xff,\r
+                pIp4Address->sin_addr.s_addr ));\r
+      pSocket->errno = EADDRNOTAVAIL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_BIND,\r
+              "ERROR - Invalid Udp4 address length: %d\r\n",\r
+              SockAddrLength ));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    pSocket->errno = EINVAL;\r
+  }\r
+  \r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Initialize the UDP4 service.\r
+\r
+  This routine initializes the UDP4 service after its service binding\r
+  protocol was located on a controller.\r
+\r
+  @param [in] pService        DT_SERVICE structure address\r
+\r
+  @retval EFI_SUCCESS         The service was properly initialized\r
+  @retval other               A failure occurred during the service initialization\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslUdpInitialize4 (\r
+  IN DT_SERVICE * pService\r
+  )\r
+{\r
+  DT_LAYER * pLayer;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Identify the service\r
+  //\r
+  pService->NetworkType = NETWORK_TYPE_UDP4;\r
+\r
+  //\r
+  //  Connect this service to the service list\r
+  //\r
+  pLayer = &mEslLayer;\r
+  pService->pNext = pLayer->pUdp4List;\r
+  pLayer->pUdp4List = pService;\r
+\r
+  //\r
+  //  Assume the list is empty\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Return the initialization status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Allocate and initialize a DT_PORT structure.\r
+\r
+  @param [in] pSocket     Address of the socket structure.\r
+  @param [in] pService    Address of the DT_SERVICE structure.\r
+  @param [in] ChildHandle Udp4 child handle\r
+  @param [in] pIpAddress  Buffer containing IP4 network address of the local host\r
+  @param [in] PortNumber  Udp4 port number\r
+  @param [in] DebugFlags  Flags for debug messages\r
+  @param [out] ppPort     Buffer to receive new DT_PORT structure address\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdpPortAllocate4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN DT_SERVICE * pService,\r
+  IN EFI_HANDLE ChildHandle,\r
+  IN CONST UINT8 * pIpAddress,\r
+  IN UINT16 PortNumber,\r
+  IN UINTN DebugFlags,\r
+  OUT DT_PORT ** ppPort\r
+  )\r
+{\r
+  UINTN LengthInBytes;\r
+  EFI_UDP4_CONFIG_DATA * pConfig;\r
+  DT_LAYER * pLayer;\r
+  DT_PORT * pPort;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Use for/break instead of goto\r
+  for ( ; ; ) {\r
+    //\r
+    //  Allocate a port structure\r
+    //\r
+    pLayer = &mEslLayer;\r
+    LengthInBytes = sizeof ( *pPort );\r
+    Status = gBS->AllocatePool ( EfiRuntimeServicesData,\r
+                                 LengthInBytes,\r
+                                 (VOID **)&pPort );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+                "ERROR - Failed to allocate the port structure, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      pPort = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+              "0x%08x: Allocate pPort, %d bytes\r\n",\r
+              pPort,\r
+              LengthInBytes ));\r
+\r
+    //\r
+    //  Initialize the port\r
+    //\r
+    ZeroMem ( pPort, LengthInBytes );\r
+    pPort->Signature = PORT_SIGNATURE;\r
+    pPort->pService = pService;\r
+    pPort->pSocket = pSocket;\r
+    pPort->pfnCloseStart = EslUdpPortCloseStart4;\r
+    pPort->DebugFlags = DebugFlags;\r
+\r
+    //\r
+    //  Allocate the receive event\r
+    //\r
+    pUdp4 = &pPort->Context.Udp4;\r
+    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
+                                 TPL_SOCKETS,\r
+                                 (EFI_EVENT_NOTIFY)EslUdpRxComplete4,\r
+                                 pPort,\r
+                                 &pUdp4->RxToken.Event);\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to create the receive event, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_RX | DEBUG_POOL,\r
+              "0x%08x: Created receive event\r\n",\r
+              pUdp4->RxToken.Event ));\r
+\r
+    //\r
+    //  Allocate the transmit event\r
+    //\r
+    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
+                                 TPL_SOCKETS,\r
+                                 (EFI_EVENT_NOTIFY)EslUdpTxComplete4,\r
+                                 pPort,\r
+                                 &pUdp4->TxToken.Event);\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to create the transmit event, Status: %r\r\n",\r
+                Status ));\r
+      pSocket->errno = ENOMEM;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_CLOSE | DEBUG_POOL,\r
+              "0x%08x: Created transmit event\r\n",\r
+              pUdp4->TxToken.Event ));\r
+\r
+    //\r
+    //  Open the port protocol\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    ChildHandle,\r
+                    &gEfiUdp4ProtocolGuid,\r
+                    (VOID **) &pUdp4->pProtocol,\r
+                    pLayer->ImageHandle,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to open gEfiUdp4ProtocolGuid on controller 0x%08x\r\n",\r
+                pUdp4->Handle ));\r
+      pSocket->errno = EEXIST;\r
+      break;\r
+    }\r
+    DEBUG (( DebugFlags,\r
+              "0x%08x: gEfiUdp4ProtocolGuid opened on controller 0x%08x\r\n",\r
+              pUdp4->pProtocol,\r
+              ChildHandle ));\r
+\r
+    //\r
+    //  Set the port address\r
+    //\r
+    pUdp4->Handle = ChildHandle;\r
+    pConfig = &pPort->Context.Udp4.ConfigData;\r
+    pConfig->StationPort = PortNumber;\r
+    if (( 0 == pIpAddress[0])\r
+      && ( 0 == pIpAddress[1])\r
+      && ( 0 == pIpAddress[2])\r
+      && ( 0 == pIpAddress[3])) {\r
+      pConfig->UseDefaultAddress = TRUE;\r
+    }\r
+    else {\r
+      pConfig->StationAddress.Addr[0] = pIpAddress[0];\r
+      pConfig->StationAddress.Addr[1] = pIpAddress[1];\r
+      pConfig->StationAddress.Addr[2] = pIpAddress[2];\r
+      pConfig->StationAddress.Addr[3] = pIpAddress[3];\r
+      pConfig->SubnetMask.Addr[0] = 0xff;\r
+      pConfig->SubnetMask.Addr[1] = 0xff;\r
+      pConfig->SubnetMask.Addr[2] = 0xff;\r
+      pConfig->SubnetMask.Addr[3] = 0xff;\r
+    }\r
+    pConfig->TimeToLive = 255;\r
+    pConfig->AcceptAnyPort = FALSE;\r
+    pConfig->AcceptBroadcast = FALSE;\r
+    pConfig->AcceptPromiscuous = FALSE;\r
+    pConfig->AllowDuplicatePort = TRUE;\r
+    pConfig->DoNotFragment = TRUE;\r
+\r
+    //\r
+    //  Verify the socket layer synchronization\r
+    //\r
+    VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+    //\r
+    //  Add this port to the socket\r
+    //\r
+    pPort->pLinkSocket = pSocket->pPortList;\r
+    pSocket->pPortList = pPort;\r
+    DEBUG (( DebugFlags,\r
+              "0x%08x: Socket adding port: 0x%08x\r\n",\r
+              pSocket,\r
+              pPort ));\r
+\r
+    //\r
+    //  Add this port to the service\r
+    //\r
+    pPort->pLinkService = pService->pPortList;\r
+    pService->pPortList = pPort;\r
+\r
+    //\r
+    //  Return the port\r
+    //\r
+    *ppPort = pPort;\r
+    break;\r
+  }\r
+\r
+  //\r
+  //  Clean up after the error if necessary\r
+  //\r
+  if (( EFI_ERROR ( Status )) && ( NULL != pPort )) {\r
+    //\r
+    //  Close the port\r
+    //\r
+    EslUdpPortClose4 ( pPort );\r
+  }\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Close a UDP4 port.\r
+\r
+  This routine releases the resources allocated by\r
+  ::UdpPortAllocate4().\r
+  \r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS     The port is closed\r
+  @retval other           Port close error\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpPortClose4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  UINTN DebugFlags;\r
+  DT_LAYER * pLayer;\r
+  DT_PACKET * pPacket;\r
+  DT_PORT * pPreviousPort;\r
+  DT_SERVICE * pService;\r
+  DT_SOCKET * pSocket;\r
+  EFI_SERVICE_BINDING_PROTOCOL * pUdp4Service;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_STATUS Status;\r
+  \r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  pSocket = pPort->pSocket;\r
+  pSocket->errno = 0;\r
+\r
+  //\r
+  //  Locate the port in the socket list\r
+  //\r
+  pLayer = &mEslLayer;\r
+  DebugFlags = pPort->DebugFlags;\r
+  pPreviousPort = pSocket->pPortList;\r
+  if ( pPreviousPort == pPort ) {\r
+    //\r
+    //  Remove this port from the head of the socket list\r
+    //\r
+    pSocket->pPortList = pPort->pLinkSocket;\r
+  }\r
+  else {\r
+    //\r
+    //  Locate the port in the middle of the socket list\r
+    //\r
+    while (( NULL != pPreviousPort )\r
+      && ( pPreviousPort->pLinkSocket != pPort )) {\r
+      pPreviousPort = pPreviousPort->pLinkSocket;\r
+    }\r
+    if ( NULL != pPreviousPort ) {\r
+      //\r
+      //  Remove the port from the middle of the socket list\r
+      //\r
+      pPreviousPort->pLinkSocket = pPort->pLinkSocket;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Locate the port in the service list\r
+  //\r
+  pService = pPort->pService;\r
+  pPreviousPort = pService->pPortList;\r
+  if ( pPreviousPort == pPort ) {\r
+    //\r
+    //  Remove this port from the head of the service list\r
+    //\r
+    pService->pPortList = pPort->pLinkService;\r
+  }\r
+  else {\r
+    //\r
+    //  Locate the port in the middle of the service list\r
+    //\r
+    while (( NULL != pPreviousPort )\r
+      && ( pPreviousPort->pLinkService != pPort )) {\r
+      pPreviousPort = pPreviousPort->pLinkService;\r
+    }\r
+    if ( NULL != pPreviousPort ) {\r
+      //\r
+      //  Remove the port from the middle of the service list\r
+      //\r
+      pPreviousPort->pLinkService = pPort->pLinkService;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Empty the receive queue\r
+  //\r
+  ASSERT ( NULL == pSocket->pRxPacketListHead );\r
+  ASSERT ( NULL == pSocket->pRxPacketListTail );\r
+  ASSERT ( 0 == pSocket->RxBytes );\r
+\r
+  //\r
+  //  Empty the receive free queue\r
+  //\r
+  while ( NULL != pSocket->pRxFree ) {\r
+    pPacket = pSocket->pRxFree;\r
+    pSocket->pRxFree = pPacket->pNext;\r
+    EslSocketPacketFree ( pPacket, DEBUG_RX );\r
+  }\r
+\r
+  //\r
+  //  Done with the receive event\r
+  //\r
+  pUdp4 = &pPort->Context.Udp4;\r
+  if ( NULL != pUdp4->RxToken.Event ) {\r
+    Status = gBS->CloseEvent ( pUdp4->RxToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Closed receive event\r\n",\r
+                pUdp4->RxToken.Event ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close the receive event, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the transmit event\r
+  //\r
+  if ( NULL != pUdp4->TxToken.Event ) {\r
+    Status = gBS->CloseEvent ( pUdp4->TxToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Closed normal transmit event\r\n",\r
+                pUdp4->TxToken.Event ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close the normal transmit event, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the UDP protocol\r
+  //\r
+  pUdp4Service = pService->pInterface;\r
+  if ( NULL != pUdp4->pProtocol ) {\r
+    Status = gBS->CloseProtocol ( pUdp4->Handle,\r
+                                  &gEfiUdp4ProtocolGuid,\r
+                                  pLayer->ImageHandle,\r
+                                  NULL );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags,\r
+                "0x%08x: gEfiUdp4ProtocolGuid closed on controller 0x%08x\r\n",\r
+                pUdp4->pProtocol,\r
+                pUdp4->Handle ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags,\r
+                "ERROR - Failed to close gEfiUdp4ProtocolGuid opened on controller 0x%08x, Status: %r\r\n",\r
+                pUdp4->Handle,\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the UDP port\r
+  //\r
+  if ( NULL != pUdp4->Handle ) {\r
+    Status = pUdp4Service->DestroyChild ( pUdp4Service,\r
+                                          pUdp4->Handle );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DebugFlags | DEBUG_POOL,\r
+                "0x%08x: Udp4 port handle destroyed\r\n",\r
+                pUdp4->Handle ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,\r
+                "ERROR - Failed to destroy the Udp4 port handle, Status: %r\r\n",\r
+                Status ));\r
+      ASSERT ( EFI_SUCCESS == Status );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Release the port structure\r
+  //\r
+  Status = gBS->FreePool ( pPort );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    DEBUG (( DebugFlags | DEBUG_POOL,\r
+              "0x%08x: Free pPort, %d bytes\r\n",\r
+              pPort,\r
+              sizeof ( *pPort )));\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_ERROR | DebugFlags | DEBUG_POOL,\r
+              "ERROR - Failed to free pPort: 0x%08x, Status: %r\r\n",\r
+              pPort,\r
+              Status ));\r
+    ASSERT ( EFI_SUCCESS == Status );\r
+  }\r
+\r
+  //\r
+  //  Mark the socket as closed if necessary\r
+  //\r
+  if ( NULL == pSocket->pPortList ) {\r
+    pSocket->State = SOCKET_STATE_CLOSED;\r
+    DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+              "0x%08x: Socket State: SOCKET_STATE_CLOSED\r\n",\r
+              pSocket ));\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Start the close operation on a UDP4 port, state 1.\r
+\r
+  Closing a port goes through the following states:\r
+  1. Port close starting - Mark the port as closing and wait for transmission to complete\r
+  2. Port TX close done - Transmissions complete, close the port and abort the receives\r
+  3. Port RX close done - Receive operations complete, close the port\r
+  4. Port closed - Release the port resources\r
+  \r
+  @param [in] pPort       Address of the port structure.\r
+  @param [in] bCloseNow   Set TRUE to abort active transfers\r
+  @param [in] DebugFlags  Flags for debug messages\r
+\r
+  @retval EFI_SUCCESS         The port is closed, not normally returned\r
+  @retval EFI_NOT_READY       The port has started the closing process\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpPortCloseStart4 (\r
+  IN DT_PORT * pPort,\r
+  IN BOOLEAN bCloseNow,\r
+  IN UINTN DebugFlags\r
+  )\r
+{\r
+  DT_SOCKET * pSocket;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Mark the port as closing\r
+  //\r
+  Status = EFI_ALREADY_STARTED;\r
+  pSocket = pPort->pSocket;\r
+  pSocket->errno = EALREADY;\r
+  if ( PORT_STATE_CLOSE_STARTED > pPort->State ) {\r
+\r
+    //\r
+    //  Update the port state\r
+    //\r
+    pPort->State = PORT_STATE_CLOSE_STARTED;\r
+    DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+              "0x%08x: Port Close State: PORT_STATE_CLOSE_STARTED\r\n",\r
+              pPort ));\r
+    pPort->bCloseNow = bCloseNow;\r
+    pPort->DebugFlags = DebugFlags;\r
+\r
+    //\r
+    //  Determine if transmits are complete\r
+    //\r
+    Status = EslUdpPortCloseTxDone4 ( pPort );\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Port close state 3\r
+\r
+  Continue the close operation after the receive is complete.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS         The port is closed\r
+  @retval EFI_NOT_READY       The port is still closing\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpPortCloseRxDone4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  PORT_STATE PortState;\r
+  DT_SOCKET * pSocket;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Verify that the port is closing\r
+  //\r
+  Status = EFI_ALREADY_STARTED;\r
+  pSocket = pPort->pSocket;\r
+  pSocket->errno = EALREADY;\r
+  PortState = pPort->State;\r
+  if (( PORT_STATE_CLOSE_TX_DONE == PortState )\r
+    || ( PORT_STATE_CLOSE_DONE == PortState )) {\r
+    //\r
+    //  Determine if the receive operation is pending\r
+    //\r
+    Status = EFI_NOT_READY;\r
+    pSocket->errno = EAGAIN;\r
+    pUdp4 = &pPort->Context.Udp4;\r
+    if ( NULL == pUdp4->pReceivePending ) {\r
+      //\r
+      //  The receive operation is complete\r
+      //  Update the port state\r
+      //\r
+      pPort->State = PORT_STATE_CLOSE_RX_DONE;\r
+      DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                "0x%08x: Port Close State: PORT_STATE_CLOSE_RX_DONE\r\n",\r
+                pPort ));\r
+\r
+      //\r
+      //  The close operation has completed\r
+      //  Release the port resources\r
+      //\r
+      Status = EslUdpPortClose4 ( pPort );\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                "0x%08x: Port Close: Receive still pending!\r\n",\r
+                pPort ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Port close state 2\r
+\r
+  Continue the close operation after the transmission is complete.\r
+\r
+  @param [in] pPort       Address of the port structure.\r
+\r
+  @retval EFI_SUCCESS         The port is closed, not normally returned\r
+  @retval EFI_NOT_READY       The port is still closing\r
+  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
+                              most likely the routine was called already.\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpPortCloseTxDone4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  DT_PACKET * pPacket;\r
+  DT_SOCKET * pSocket;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_UDP4_PROTOCOL * pUdp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  All transmissions are complete or must be stopped\r
+  //  Mark the port as TX complete\r
+  //\r
+  Status = EFI_ALREADY_STARTED;\r
+  if ( PORT_STATE_CLOSE_STARTED == pPort->State ) {\r
+    //\r
+    //  Verify that the transmissions are complete\r
+    //\r
+    pSocket = pPort->pSocket;\r
+    if ( pPort->bCloseNow\r
+         || ( EFI_SUCCESS != pSocket->TxError )\r
+         || ( 0 == pSocket->TxBytes )) {\r
+      //\r
+      //  Start the close operation on the port\r
+      //\r
+      pUdp4 = &pPort->Context.Udp4;\r
+      pUdp4Protocol = pUdp4->pProtocol;\r
+      if ( !pUdp4->bConfigured ) {\r
+        //\r
+        //  Skip the close operation since the port is not\r
+        //  configured\r
+        //\r
+        //  Update the port state\r
+        //\r
+        pPort->State = PORT_STATE_CLOSE_DONE;\r
+        DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                  "0x%08x: Port Close State: PORT_STATE_CLOSE_DONE\r\n",\r
+                  pPort ));\r
+        Status = EFI_SUCCESS;\r
+      }\r
+      else {\r
+        //\r
+        //  Update the port state\r
+        //\r
+        pPort->State = PORT_STATE_CLOSE_TX_DONE;\r
+        DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                  "0x%08x: Port Close State: PORT_STATE_CLOSE_TX_DONE\r\n",\r
+                  pPort ));\r
+\r
+        //\r
+        //  Empty the receive queue\r
+        //\r
+        while ( NULL != pSocket->pRxPacketListHead ) {\r
+          pPacket = pSocket->pRxPacketListHead;\r
+          pSocket->pRxPacketListHead = pPacket->pNext;\r
+          pSocket->RxBytes -= pPacket->Op.Udp4Rx.pRxData->DataLength;\r
+\r
+          //\r
+          //  Return the buffer to the UDP4 driver\r
+          //\r
+          gBS->SignalEvent ( pPacket->Op.Udp4Rx.pRxData->RecycleSignal );\r
+\r
+          //\r
+          //  Done with this packet\r
+          //\r
+          EslSocketPacketFree ( pPacket, DEBUG_RX );\r
+        }\r
+        pSocket->pRxPacketListTail = NULL;\r
+        ASSERT ( 0 == pSocket->RxBytes );\r
+\r
+        //\r
+        //  Reset the port, cancel the outstanding receive\r
+        //\r
+        Status = pUdp4Protocol->Configure ( pUdp4Protocol,\r
+                                            NULL );\r
+        if ( !EFI_ERROR ( Status )) {\r
+          DEBUG (( pPort->DebugFlags | DEBUG_CLOSE | DEBUG_INFO,\r
+                    "0x%08x: Port reset\r\n",\r
+                    pPort ));\r
+\r
+          //\r
+          //  Free the receive packet\r
+          //\r
+          Status = gBS->CheckEvent ( pUdp4->RxToken.Event );\r
+          if ( EFI_SUCCESS != Status ) {\r
+            EslSocketPacketFree ( pUdp4->pReceivePending, DEBUG_CLOSE );\r
+            pUdp4->pReceivePending = NULL;\r
+            Status = EFI_SUCCESS;\r
+          }\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_ERROR | pPort->DebugFlags | DEBUG_CLOSE | DEBUG_INFO,\r
+                   "ERROR - Port 0x%08x reset failed, Status: %r\r\n",\r
+                   pPort,\r
+                   Status ));\r
+          ASSERT ( EFI_SUCCESS == Status );\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Determine if the receive operation is pending\r
+      //\r
+      if ( !EFI_ERROR ( Status )) {\r
+        Status = EslUdpPortCloseRxDone4 ( pPort );\r
+      }\r
+    }\r
+    else {\r
+      //\r
+      //  Transmissions are still active, exit\r
+      //\r
+      DEBUG (( DEBUG_CLOSE | DEBUG_INFO,\r
+                "0x%08x: Port Close: Transmits are still pending!\r\n",\r
+                pPort ));\r
+      Status = EFI_NOT_READY;\r
+      pSocket->errno = EAGAIN;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Connect to a remote system via the network.\r
+\r
+  The ::UdpConnectStart4= routine sets the remote address for the connection.\r
+\r
+  @param [in] pSocket         Address of the socket structure.\r
+\r
+  @param [in] pSockAddr       Network address of the remote system.\r
+    \r
+  @param [in] SockAddrLength  Length in bytes of the network address.\r
+  \r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdpConnect4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength\r
+  )\r
+{\r
+  struct sockaddr_in LocalAddress;\r
+  DT_PORT * pPort;\r
+  struct sockaddr_in * pRemoteAddress;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_NETWORK_UNREACHABLE;\r
+  pSocket->errno = ENETUNREACH;\r
+\r
+  //\r
+  //  Get the address\r
+  //\r
+  pRemoteAddress = (struct sockaddr_in *)pSockAddr;\r
+\r
+  //\r
+  //  Validate the address length\r
+  //\r
+  if ( SockAddrLength >= ( sizeof ( *pRemoteAddress )\r
+                           - sizeof ( pRemoteAddress->sin_zero ))) {\r
+    //\r
+    //  Determine if BIND was already called\r
+    //\r
+    if ( NULL == pSocket->pPortList ) {\r
+      //\r
+      //  Allow any local port\r
+      //\r
+      ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));\r
+      LocalAddress.sin_len = sizeof ( LocalAddress );\r
+      LocalAddress.sin_family = AF_INET;\r
+      Status = EslSocketBind ( &pSocket->SocketProtocol,\r
+                               (struct sockaddr *)&LocalAddress,\r
+                               LocalAddress.sin_len,\r
+                               &pSocket->errno );\r
+    }\r
+\r
+    //\r
+    //  Walk the list of ports\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    while ( NULL != pPort ) {\r
+      //\r
+      //  Set the remote address\r
+      //\r
+      pUdp4 = &pPort->Context.Udp4;\r
+      pUdp4->ConfigData.RemoteAddress.Addr[0] = (UINT8)( pRemoteAddress->sin_addr.s_addr );\r
+      pUdp4->ConfigData.RemoteAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );\r
+      pUdp4->ConfigData.RemoteAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );\r
+      pUdp4->ConfigData.RemoteAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );\r
+      pUdp4->ConfigData.RemotePort = SwapBytes16 ( pRemoteAddress->sin_port );\r
+\r
+      //\r
+      //  At least one path exists\r
+      //\r
+      Status = EFI_SUCCESS;\r
+      pSocket->errno = 0;\r
+\r
+      //\r
+      //  Set the next port\r
+      //\r
+      pPort = pPort->pLinkSocket;\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_CONNECT,\r
+              "ERROR - Invalid UDP4 address length: %d\r\n",\r
+              SockAddrLength ));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    pSocket->errno = EINVAL;\r
+  }\r
+\r
+  //\r
+  //  Return the connect status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Get the local socket address\r
+\r
+  @param [in] pSocket             Address of the socket structure.\r
+\r
+  @param [out] pAddress           Network address to receive the local system address\r
+\r
+  @param [in,out] pAddressLength  Length of the local network address structure\r
+\r
+  @retval EFI_SUCCESS - Address available\r
+  @retval Other - Failed to get the address\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpGetLocalAddress4 (\r
+  IN DT_SOCKET * pSocket,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  )\r
+{\r
+  socklen_t LengthInBytes;\r
+  DT_PORT * pPort;\r
+  struct sockaddr_in * pLocalAddress;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Verify that there is just a single connection\r
+  //\r
+  pPort = pSocket->pPortList;\r
+  if (( NULL != pPort ) && ( NULL == pPort->pLinkSocket )) {\r
+    //\r
+    //  Verify the address length\r
+    //\r
+    LengthInBytes = sizeof ( struct sockaddr_in );\r
+    if ( LengthInBytes <= * pAddressLength ) {\r
+      //\r
+      //  Return the local address\r
+      //\r
+      pUdp4 = &pPort->Context.Udp4;\r
+      pLocalAddress = (struct sockaddr_in *)pAddress;\r
+      ZeroMem ( pLocalAddress, LengthInBytes );\r
+      pLocalAddress->sin_family = AF_INET;\r
+      pLocalAddress->sin_len = (uint8_t)LengthInBytes;\r
+      pLocalAddress->sin_port = SwapBytes16 ( pUdp4->ConfigData.StationPort );\r
+      CopyMem ( &pLocalAddress->sin_addr,\r
+                &pUdp4->ConfigData.StationAddress.Addr[0],\r
+                sizeof ( pLocalAddress->sin_addr ));\r
+      pSocket->errno = 0;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+    else {\r
+      pSocket->errno = EINVAL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  else {\r
+    pSocket->errno = ENOTCONN;\r
+    Status = EFI_NOT_STARTED;\r
+  }\r
+  \r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Get the remote socket address\r
+\r
+  @param [in] pSocket             Address of the socket structure.\r
+\r
+  @param [out] pAddress           Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Address available\r
+  @retval Other - Failed to get the address\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpGetRemoteAddress4 (\r
+  IN DT_SOCKET * pSocket,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  )\r
+{\r
+  socklen_t LengthInBytes;\r
+  DT_PORT * pPort;\r
+  struct sockaddr_in * pRemoteAddress;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Verify that there is just a single connection\r
+  //\r
+  pPort = pSocket->pPortList;\r
+  if (( NULL != pPort ) && ( NULL == pPort->pLinkSocket )) {\r
+    //\r
+    //  Verify the address length\r
+    //\r
+    LengthInBytes = sizeof ( struct sockaddr_in );\r
+    if ( LengthInBytes <= * pAddressLength ) {\r
+      //\r
+      //  Return the local address\r
+      //\r
+      pUdp4 = &pPort->Context.Udp4;\r
+      pRemoteAddress = (struct sockaddr_in *)pAddress;\r
+      ZeroMem ( pRemoteAddress, LengthInBytes );\r
+      pRemoteAddress->sin_family = AF_INET;\r
+      pRemoteAddress->sin_len = (uint8_t)LengthInBytes;\r
+      pRemoteAddress->sin_port = SwapBytes16 ( pUdp4->ConfigData.RemotePort );\r
+      CopyMem ( &pRemoteAddress->sin_addr,\r
+                &pUdp4->ConfigData.RemoteAddress.Addr[0],\r
+                sizeof ( pRemoteAddress->sin_addr ));\r
+      pSocket->errno = 0;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+    else {\r
+      pSocket->errno = EINVAL;\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  else {\r
+    pSocket->errno = ENOTCONN;\r
+    Status = EFI_NOT_STARTED;\r
+  }\r
+  \r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Receive data from a network connection.\r
+\r
+  To minimize the number of buffer copies, the ::UdpRxComplete4\r
+  routine queues the UDP4 driver's buffer to a list of datagrams\r
+  waiting to be received.  The socket driver holds on to the\r
+  buffers from the UDP4 driver until the application layer requests\r
+  the data or the socket is closed.\r
+\r
+  The application calls this routine in the socket layer to\r
+  receive datagrams from one or more remote systems. This routine\r
+  removes the next available datagram from the list of datagrams\r
+  and copies the data from the UDP4 driver's buffer into the\r
+  application's buffer.  The UDP4 driver's buffer is then returned.\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+\r
+  @param [in] Flags           Message control flags\r
+\r
+  @param [in] BufferLength    Length of the the buffer\r
+\r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+\r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpReceive4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN INT32 Flags,\r
+  IN size_t BufferLength,\r
+  IN UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength\r
+  )\r
+{\r
+  socklen_t AddressLength;\r
+  size_t BytesToCopy;\r
+  size_t DataBytes;\r
+  UINT32 Fragment;\r
+  in_addr_t IpAddress;\r
+  size_t LengthInBytes;\r
+  UINT8 * pData;\r
+  DT_PACKET * pPacket;\r
+  DT_PORT * pPort;\r
+  struct sockaddr_in * pRemoteAddress;\r
+  EFI_UDP4_RECEIVE_DATA * pRxData;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  struct sockaddr_in RemoteAddress;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+  pSocket->errno = ENOTCONN;\r
+\r
+  //\r
+  //  Verify that the socket is connected\r
+  //\r
+  if (( SOCKET_STATE_CONNECTED == pSocket->State )\r
+    || ( PORT_STATE_RX_ERROR == pSocket->State )) {\r
+    //\r
+    //  Locate the port\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    if ( NULL != pPort ) {\r
+      //\r
+      //  Determine if there is any data on the queue\r
+      //\r
+      pUdp4 = &pPort->Context.Udp4;\r
+      pPacket = pSocket->pRxPacketListHead;\r
+      if ( NULL != pPacket ) {\r
+        //\r
+        //  Validate the return address parameters\r
+        //\r
+        pRxData = pPacket->Op.Udp4Rx.pRxData;\r
+        if (( NULL == pAddress ) || ( NULL != pAddressLength )) {\r
+          //\r
+          //  Return the remote system address if requested\r
+          //\r
+          if ( NULL != pAddress ) {\r
+            //\r
+            //  Build the remote address\r
+            //\r
+            DEBUG (( DEBUG_RX,\r
+                      "Getting packet source address: %d.%d.%d.%d:%d\r\n",\r
+                      pRxData->UdpSession.SourceAddress.Addr[0],\r
+                      pRxData->UdpSession.SourceAddress.Addr[1],\r
+                      pRxData->UdpSession.SourceAddress.Addr[2],\r
+                      pRxData->UdpSession.SourceAddress.Addr[3],\r
+                      pRxData->UdpSession.SourcePort ));\r
+            ZeroMem ( &RemoteAddress, sizeof ( RemoteAddress ));\r
+            RemoteAddress.sin_len = sizeof ( RemoteAddress );\r
+            RemoteAddress.sin_family = AF_INET;\r
+            IpAddress = pRxData->UdpSession.SourceAddress.Addr[3];\r
+            IpAddress <<= 8;\r
+            IpAddress |= pRxData->UdpSession.SourceAddress.Addr[2];\r
+            IpAddress <<= 8;\r
+            IpAddress |= pRxData->UdpSession.SourceAddress.Addr[1];\r
+            IpAddress <<= 8;\r
+            IpAddress |= pRxData->UdpSession.SourceAddress.Addr[0];\r
+            RemoteAddress.sin_addr.s_addr = IpAddress;\r
+            RemoteAddress.sin_port = SwapBytes16 ( pRxData->UdpSession.SourcePort );\r
+\r
+            //\r
+            //  Copy the address\r
+            //\r
+            pRemoteAddress = (struct sockaddr_in *)pAddress;\r
+            AddressLength = sizeof ( *pRemoteAddress );\r
+            if ( AddressLength > *pAddressLength ) {\r
+              AddressLength = *pAddressLength;\r
+            }\r
+            CopyMem ( pRemoteAddress,\r
+                      &RemoteAddress,\r
+                      AddressLength );\r
+\r
+            //\r
+            //  Update the address length\r
+            //\r
+            *pAddressLength = AddressLength;\r
+          }\r
+\r
+          //\r
+          //  Reduce the buffer length if necessary\r
+          //\r
+          DataBytes = pRxData->DataLength;\r
+          if ( DataBytes < BufferLength ) {\r
+            BufferLength = DataBytes;\r
+          }\r
+\r
+          //\r
+          //  Copy the received data\r
+          //\r
+          LengthInBytes = 0;\r
+          Fragment = 0;\r
+          do {\r
+            //\r
+            //  Determine the amount of received data\r
+            //\r
+            pData = pRxData->FragmentTable[Fragment].FragmentBuffer;\r
+            BytesToCopy = pRxData->FragmentTable[Fragment].FragmentLength;\r
+            if (( BufferLength - LengthInBytes ) < BytesToCopy ) {\r
+              BytesToCopy = BufferLength - LengthInBytes;\r
+            }\r
+            LengthInBytes += BytesToCopy;\r
+\r
+            //\r
+            //  Move the data into the buffer\r
+            //\r
+            DEBUG (( DEBUG_RX,\r
+                      "0x%08x: Port copy packet 0x%08x data into 0x%08x, 0x%08x bytes\r\n",\r
+                      pPort,\r
+                      pPacket,\r
+                      pBuffer,\r
+                      BytesToCopy ));\r
+            CopyMem ( pBuffer, pData, BytesToCopy );\r
+          } while ( BufferLength > LengthInBytes );\r
+\r
+          //\r
+          //  Determine if the data is being read\r
+          //\r
+          if ( 0 == ( Flags & MSG_PEEK )) {\r
+            //\r
+            //  Display for the bytes consumed\r
+            //\r
+            DEBUG (( DEBUG_RX,\r
+                      "0x%08x: Port account for 0x%08x bytes\r\n",\r
+                      pPort,\r
+                      BufferLength ));\r
+\r
+            //\r
+            //  All done with this packet\r
+            //  Account for any discarded data\r
+            //\r
+            pSocket->RxBytes -= DataBytes;\r
+            if ( 0 != ( DataBytes - BufferLength )) {\r
+              DEBUG (( DEBUG_RX,\r
+                        "0x%08x: Port, packet read, skipping over 0x%08x bytes\r\n",\r
+                        pPort,\r
+                        DataBytes - BufferLength ));\r
+            }\r
+\r
+            //\r
+            //  Remove this packet from the queue\r
+            //\r
+            pSocket->pRxPacketListHead = pPacket->pNext;\r
+            if ( NULL == pSocket->pRxPacketListHead ) {\r
+              pSocket->pRxPacketListTail = NULL;\r
+            }\r
+\r
+            //\r
+            //  Return this packet to the UDP4 driver\r
+            //\r
+            gBS->SignalEvent ( pRxData->RecycleSignal );\r
+\r
+            //\r
+            //  Move the packet to the free queue\r
+            //\r
+            pPacket->pNext = pSocket->pRxFree;\r
+            pSocket->pRxFree = pPacket;\r
+            DEBUG (( DEBUG_RX,\r
+                      "0x%08x: Port freeing packet 0x%08x\r\n",\r
+                      pPort,\r
+                      pPacket ));\r
+\r
+            //\r
+            //  Restart this receive operation if necessary\r
+            //\r
+            if (( NULL == pUdp4->pReceivePending )\r
+              && ( MAX_RX_DATA > pSocket->RxBytes )) {\r
+                EslUdpRxStart4 ( pPort );\r
+            }\r
+          }\r
+\r
+          //\r
+          //  Return the data length\r
+          //\r
+          *pDataLength = LengthInBytes;\r
+\r
+          //\r
+          //  Successful operation\r
+          //\r
+          Status = EFI_SUCCESS;\r
+          pSocket->errno = 0;\r
+        }\r
+        else {\r
+          //\r
+          //  Bad return address pointer and length\r
+          //\r
+          Status = EFI_INVALID_PARAMETER;\r
+          pSocket->errno = EINVAL;\r
+        }\r
+      }\r
+      else {\r
+        //\r
+        //  The queue is empty\r
+        //  Determine if it is time to return the receive error\r
+        //\r
+        if ( EFI_ERROR ( pSocket->RxError )) {\r
+          Status = pSocket->RxError;\r
+          switch ( Status ) {\r
+          default:\r
+            pSocket->errno = EIO;\r
+            break;\r
+\r
+          case EFI_HOST_UNREACHABLE:\r
+            pSocket->errno = EHOSTUNREACH;\r
+            break;\r
+\r
+          case EFI_NETWORK_UNREACHABLE:\r
+            pSocket->errno = ENETUNREACH;\r
+            break;\r
+\r
+          case EFI_PORT_UNREACHABLE:\r
+            pSocket->errno = EPROTONOSUPPORT;\r
+            break;\r
+\r
+          case EFI_PROTOCOL_UNREACHABLE:\r
+            pSocket->errno = ENOPROTOOPT;\r
+            break;\r
+          }\r
+          pSocket->RxError = EFI_SUCCESS;\r
+        }\r
+        else {\r
+          Status = EFI_NOT_READY;\r
+          pSocket->errno = EAGAIN;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Cancel the receive operations\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @retval EFI_SUCCESS - The cancel was successful\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdpRxCancel4 (\r
+  IN DT_SOCKET * pSocket\r
+  )\r
+{\r
+  DT_PACKET * pPacket;\r
+  DT_PORT * pPort;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_UDP4_PROTOCOL * pUdp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_NOT_FOUND;\r
+\r
+  //\r
+  //  Locate the port\r
+  //\r
+  pPort = pSocket->pPortList;\r
+  if ( NULL != pPort ) {\r
+    //\r
+    //  Determine if a receive is pending\r
+    //\r
+    pUdp4 = &pPort->Context.Udp4;\r
+    pPacket = pUdp4->pReceivePending;\r
+    if ( NULL != pPacket ) {\r
+      //\r
+      //  Attempt to cancel the receive operation\r
+      //\r
+      pUdp4Protocol = pUdp4->pProtocol;\r
+      Status = pUdp4Protocol->Cancel ( pUdp4Protocol,\r
+                                       &pUdp4->RxToken );\r
+      if ( EFI_NOT_FOUND == Status ) {\r
+        //\r
+        //  The receive is complete\r
+        //\r
+        Status = EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Process the receive completion\r
+\r
+  Keep the UDP4 driver's buffer and append it to the list of\r
+  datagrams for the application to receive.  The UDP4 driver's\r
+  buffer will be returned by either ::UdpReceive4 or\r
+  ::UdpPortCloseTxDone4.\r
+\r
+  @param  Event         The receive completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslUdpRxComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  size_t LengthInBytes;\r
+  DT_PACKET * pPacket;\r
+  DT_PACKET * pPrevious;\r
+  EFI_UDP4_RECEIVE_DATA * pRxData;\r
+  DT_SOCKET * pSocket;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_STATUS Status;\r
+  \r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Mark this receive complete\r
+  //\r
+  pUdp4 = &pPort->Context.Udp4;\r
+  pPacket = pUdp4->pReceivePending;\r
+  pUdp4->pReceivePending = NULL;\r
+  \r
+  //\r
+  //  Determine if this receive was successful\r
+  //\r
+  pSocket = pPort->pSocket;\r
+  Status = pUdp4->RxToken.Status;\r
+  if (( !EFI_ERROR ( Status )) && ( !pSocket->bRxDisable )) {\r
+    pRxData = pUdp4->RxToken.Packet.RxData;\r
+    if ( PORT_STATE_CLOSE_STARTED >= pPort->State ) {\r
+      //\r
+      //  Save the data in the packet\r
+      //\r
+      pPacket->Op.Udp4Rx.pRxData = pRxData;\r
+\r
+      //\r
+      //  Queue this packet\r
+      //\r
+      pPrevious = pSocket->pRxPacketListTail;\r
+      if ( NULL == pPrevious ) {\r
+        pSocket->pRxPacketListHead = pPacket;\r
+      }\r
+      else {\r
+        pPrevious->pNext = pPacket;\r
+      }\r
+      pSocket->pRxPacketListTail = pPacket;\r
+\r
+      //\r
+      //  Account for the normal data\r
+      //\r
+      LengthInBytes = pRxData->DataLength;\r
+      pSocket->RxBytes += LengthInBytes;\r
+\r
+      //\r
+      //  Log the received data\r
+      //\r
+      DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+                "Received packet from: %d.%d.%d.%d:%d\r\n",\r
+                pRxData->UdpSession.SourceAddress.Addr[0],\r
+                pRxData->UdpSession.SourceAddress.Addr[1],\r
+                pRxData->UdpSession.SourceAddress.Addr[2],\r
+                pRxData->UdpSession.SourceAddress.Addr[3],\r
+                pRxData->UdpSession.SourcePort ));\r
+      DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+                "Received packet sent to: %d.%d.%d.%d:%d\r\n",\r
+                pRxData->UdpSession.DestinationAddress.Addr[0],\r
+                pRxData->UdpSession.DestinationAddress.Addr[1],\r
+                pRxData->UdpSession.DestinationAddress.Addr[2],\r
+                pRxData->UdpSession.DestinationAddress.Addr[3],\r
+                pRxData->UdpSession.DestinationPort ));\r
+      DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+                "0x%08x: Packet queued on port 0x%08x with 0x%08x bytes of data\r\n",\r
+                pPacket,\r
+                pPort,\r
+                LengthInBytes ));\r
+\r
+      //\r
+      //  Attempt to restart this receive operation\r
+      //\r
+      if ( pSocket->MaxRxBuf > pSocket->RxBytes ) {\r
+        EslUdpRxStart4 ( pPort );\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_RX,\r
+                  "0x%08x: Port RX suspended, 0x%08x bytes queued\r\n",\r
+                  pPort,\r
+                  pSocket->RxBytes ));\r
+      }\r
+    }\r
+    else {\r
+      //\r
+      //  The port is being closed\r
+      //  Return the buffer to the UDP4 driver\r
+      //\r
+      gBS->SignalEvent ( pRxData->RecycleSignal );\r
+\r
+      //\r
+      //  Free the packet\r
+      //\r
+      EslSocketPacketFree ( pPacket, DEBUG_RX );\r
+    }\r
+  }\r
+  else\r
+  {\r
+    DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+              "ERROR - Receiving packet 0x%08x, on port 0x%08x, Status:%r\r\n",\r
+              pPacket,\r
+              pPort,\r
+              Status ));\r
+  \r
+    //\r
+    //  Receive error, free the packet save the error\r
+    //\r
+    EslSocketPacketFree ( pPacket, DEBUG_RX );\r
+    if ( !EFI_ERROR ( pSocket->RxError )) {\r
+      pSocket->RxError = Status;\r
+    }\r
+  \r
+    //\r
+    //  Update the port state\r
+    //\r
+    if ( PORT_STATE_CLOSE_STARTED <= pPort->State ) {\r
+      EslUdpPortCloseRxDone4 ( pPort );\r
+    }\r
+    else {\r
+      if ( EFI_ERROR ( Status )) {\r
+        pPort->State = PORT_STATE_RX_ERROR;\r
+      }\r
+    }\r
+  }\r
+  \r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Start a receive operation\r
+\r
+  @param [in] pPort       Address of the DT_PORT structure.\r
+\r
+ **/\r
+VOID\r
+EslUdpRxStart4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  DT_PACKET * pPacket;\r
+  DT_SOCKET * pSocket;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_UDP4_PROTOCOL * pUdp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Determine if a receive is already pending\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  pPacket = NULL;\r
+  pSocket = pPort->pSocket;\r
+  pUdp4 = &pPort->Context.Udp4;\r
+  if ( !EFI_ERROR ( pPort->pSocket->RxError )) {\r
+    if (( NULL == pUdp4->pReceivePending )\r
+      && ( PORT_STATE_CLOSE_STARTED > pPort->State )) {\r
+      //\r
+      //  Determine if there are any free packets\r
+      //\r
+      pPacket = pSocket->pRxFree;\r
+      if ( NULL != pPacket ) {\r
+        //\r
+        //  Remove this packet from the free list\r
+        //\r
+        pSocket->pRxFree = pPacket->pNext;\r
+        DEBUG (( DEBUG_RX,\r
+                  "0x%08x: Port removed packet 0x%08x from free list\r\n",\r
+                  pPort,\r
+                  pPacket ));\r
+      }\r
+      else {\r
+        //\r
+        //  Allocate a packet structure\r
+        //\r
+        Status = EslSocketPacketAllocate ( &pPacket,\r
+                                           sizeof ( pPacket->Op.Udp4Rx ),\r
+                                           DEBUG_RX );\r
+        if ( EFI_ERROR ( Status )) {\r
+          pPacket = NULL;\r
+          DEBUG (( DEBUG_ERROR | DEBUG_RX,\r
+                    "0x%08x: Port failed to allocate RX packet, Status: %r\r\n",\r
+                    pPort,\r
+                    Status ));\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Determine if a packet is available\r
+      //\r
+      if ( NULL != pPacket ) {\r
+        //\r
+        //  Initialize the buffer for receive\r
+        //\r
+        pPacket->pNext = NULL;\r
+        pPacket->Op.Udp4Rx.pRxData = NULL;\r
+        pUdp4->RxToken.Packet.RxData = NULL;\r
+        pUdp4->pReceivePending = pPacket;\r
+\r
+        //\r
+        //  Start the receive on the packet\r
+        //\r
+        pUdp4Protocol = pUdp4->pProtocol;\r
+        Status = pUdp4Protocol->Receive ( pUdp4Protocol,\r
+                                          &pUdp4->RxToken );\r
+        if ( !EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+                    "0x%08x: Packet receive pending on port 0x%08x\r\n",\r
+                    pPacket,\r
+                    pPort ));\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_RX | DEBUG_INFO,\r
+                    "ERROR - Failed to post a receive on port 0x%08x, Status: %r\r\n",\r
+                    pPort,\r
+                    Status ));\r
+          if ( !EFI_ERROR ( pSocket->RxError )) {\r
+            //\r
+            //  Save the error status\r
+            //\r
+            pSocket->RxError = Status;\r
+          }\r
+\r
+          //\r
+          //  Free the packet\r
+          //\r
+          pUdp4->pReceivePending = NULL;\r
+          pPacket->pNext = pSocket->pRxFree;\r
+          pSocket->pRxFree = pPacket;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Shutdown the UDP4 service.\r
+\r
+  This routine undoes the work performed by ::UdpInitialize4.\r
+\r
+  @param [in] pService        DT_SERVICE structure address\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EslUdpShutdown4 (\r
+  IN DT_SERVICE * pService\r
+  )\r
+{\r
+  DT_LAYER * pLayer;\r
+  DT_PORT * pPort;\r
+  DT_SERVICE * pPreviousService;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Verify the socket layer synchronization\r
+  //\r
+  VERIFY_TPL ( TPL_SOCKETS );\r
+\r
+  //\r
+  //  Walk the list of ports\r
+  //\r
+  do {\r
+    pPort = pService->pPortList;\r
+    if ( NULL != pPort ) {\r
+      //\r
+      //  Remove the port from the port list\r
+      //\r
+      pService->pPortList = pPort->pLinkService;\r
+\r
+      //\r
+      //  Close the port\r
+      // TODO: Fix this\r
+      //\r
+//      pPort->pfnClosePort ( pPort, 0 );\r
+    }\r
+  } while ( NULL != pPort );\r
+\r
+  //\r
+  //  Remove the service from the service list\r
+  //\r
+  pLayer = &mEslLayer;\r
+  pPreviousService = pLayer->pUdp4List;\r
+  if ( pService == pPreviousService ) {\r
+    //\r
+    //  Remove the service from the beginning of the list\r
+    //\r
+    pLayer->pUdp4List = pService->pNext;\r
+  }\r
+  else {\r
+    //\r
+    //  Remove the service from the middle of the list\r
+    //\r
+    while ( NULL != pPreviousService ) {\r
+      if ( pService == pPreviousService->pNext ) {\r
+        pPreviousService->pNext = pService->pNext;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Determine if the sockedt is configured.\r
+\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+  \r
+  @retval EFI_SUCCESS - The port is connected\r
+  @retval EFI_NOT_STARTED - The port is not connected\r
+\r
+ **/\r
+ EFI_STATUS\r
+ EslUdpSocketIsConfigured4 (\r
+  IN DT_SOCKET * pSocket\r
+  )\r
+{\r
+  DT_PORT * pPort;\r
+  DT_PORT * pNextPort;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_UDP4_PROTOCOL * pUdp4Protocol;\r
+  EFI_STATUS Status;\r
+  struct sockaddr_in LocalAddress;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Configure the port if necessary\r
+  //\r
+  if ( !pSocket->bConfigured ) {\r
+    //\r
+    //  Fill in the port list if necessary\r
+    //\r
+    if ( NULL == pSocket->pPortList ) {\r
+      LocalAddress.sin_len = sizeof ( LocalAddress );\r
+      LocalAddress.sin_family = AF_INET;\r
+      LocalAddress.sin_addr.s_addr = 0;\r
+      LocalAddress.sin_port = 0;\r
+      Status = EslUdpBind4 ( pSocket,\r
+                             (struct sockaddr *)&LocalAddress,\r
+                             LocalAddress.sin_len );\r
+    }\r
+\r
+    //\r
+    //  Walk the port list\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    while ( NULL != pPort ) {\r
+      //\r
+      //  Attempt to configure the port\r
+      //\r
+      pNextPort = pPort->pLinkSocket;\r
+      pUdp4 = &pPort->Context.Udp4;\r
+      pUdp4Protocol = pUdp4->pProtocol;\r
+      Status = pUdp4Protocol->Configure ( pUdp4Protocol,\r
+                                          &pUdp4->ConfigData );\r
+      if ( EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_LISTEN,\r
+                  "ERROR - Failed to configure the Udp4 port, Status: %r\r\n",\r
+                  Status ));\r
+        switch ( Status ) {\r
+        case EFI_ACCESS_DENIED:\r
+          pSocket->errno = EACCES;\r
+          break;\r
+\r
+        default:\r
+        case EFI_DEVICE_ERROR:\r
+          pSocket->errno = EIO;\r
+          break;\r
+\r
+        case EFI_INVALID_PARAMETER:\r
+          pSocket->errno = EADDRNOTAVAIL;\r
+          break;\r
+\r
+        case EFI_NO_MAPPING:\r
+          pSocket->errno = EAFNOSUPPORT;\r
+          break;\r
+\r
+        case EFI_OUT_OF_RESOURCES:\r
+          pSocket->errno = ENOBUFS;\r
+          break;\r
+\r
+        case EFI_UNSUPPORTED:\r
+          pSocket->errno = EOPNOTSUPP;\r
+          break;\r
+        }\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_LISTEN,\r
+                  "0x%08x: Port configured\r\n",\r
+                  pPort ));\r
+        pUdp4->bConfigured = TRUE;\r
+\r
+        //\r
+        //  Start the first read on the port\r
+        //\r
+        EslUdpRxStart4 ( pPort );\r
+\r
+        //\r
+        //  The socket is connected\r
+        //\r
+        pSocket->State = SOCKET_STATE_CONNECTED;\r
+      }\r
+\r
+      //\r
+      //  Set the next port\r
+      //\r
+      pPort = pNextPort;\r
+    }\r
+\r
+    //\r
+    //  Determine the configuration status\r
+    //\r
+    if ( NULL != pSocket->pPortList ) {\r
+      pSocket->bConfigured = TRUE;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Determine the socket configuration status\r
+  //\r
+  if ( !EFI_ERROR ( Status )) {\r
+    Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
+  }\r
+  \r
+  //\r
+  //  Return the port connected state.\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Buffer data for transmission over a network connection.\r
+\r
+  This routine is called by the socket layer API to buffer\r
+  data for transmission.  The data is copied into a local buffer\r
+  freeing the application buffer for reuse upon return.  When\r
+  necessary, this routine will start the transmit engine that\r
+  performs the data transmission on the network connection.  The\r
+  transmit engine transmits the data a packet at a time over the\r
+  network connection.\r
+\r
+  Transmission errors are returned during the next transmission or\r
+  during the close operation.  Only buffering errors are returned\r
+  during the current transmission attempt.\r
+\r
+  @param [in] pSocket         Address of a DT_SOCKET structure\r
+\r
+  @param [in] Flags           Message control flags\r
+\r
+  @param [in] BufferLength    Length of the the buffer\r
+\r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+\r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [in] pAddress        Network address of the remote system address\r
+\r
+  @param [in] AddressLength   Length of the remote network address structure\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully buffered\r
+\r
+**/\r
+EFI_STATUS\r
+EslUdpTxBuffer4 (\r
+  IN DT_SOCKET * pSocket,\r
+  IN int Flags,\r
+  IN size_t BufferLength,\r
+  IN CONST UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  IN const struct sockaddr * pAddress,\r
+  IN socklen_t AddressLength\r
+  )\r
+{\r
+  DT_PACKET * pPacket;\r
+  DT_PACKET * pPreviousPacket;\r
+  DT_PACKET ** ppPacket;\r
+  DT_PORT * pPort;\r
+  const struct sockaddr_in * pRemoteAddress;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_UDP4_COMPLETION_TOKEN * pToken;\r
+  size_t * pTxBytes;\r
+  DT_UDP4_TX_DATA * pTxData;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+  pSocket->errno = ENOTCONN;\r
+  * pDataLength = 0;\r
+\r
+  //\r
+  //  Verify that the socket is connected\r
+  //\r
+  if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
+    //\r
+    //  Locate the port\r
+    //\r
+    pPort = pSocket->pPortList;\r
+    if ( NULL != pPort ) {\r
+      //\r
+      //  Determine the queue head\r
+      //\r
+      pUdp4 = &pPort->Context.Udp4;\r
+      ppPacket = &pUdp4->pTxPacket;\r
+      pToken = &pUdp4->TxToken;\r
+      pTxBytes = &pSocket->TxBytes;\r
+\r
+      //\r
+      //  Verify that there is enough room to buffer another\r
+      //  transmit operation\r
+      //\r
+      if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
+        //\r
+        //  Attempt to allocate the packet\r
+        //\r
+        Status = EslSocketPacketAllocate ( &pPacket,\r
+                                           sizeof ( pPacket->Op.Udp4Tx )\r
+                                           - sizeof ( pPacket->Op.Udp4Tx.Buffer )\r
+                                           + BufferLength,\r
+                                           DEBUG_TX );\r
+        if ( !EFI_ERROR ( Status )) {\r
+          //\r
+          //  Initialize the transmit operation\r
+          //\r
+          pTxData = &pPacket->Op.Udp4Tx;\r
+          pTxData->TxData.GatewayAddress = NULL;\r
+          pTxData->TxData.UdpSessionData = NULL;\r
+          pTxData->TxData.DataLength = (UINT32) BufferLength;\r
+          pTxData->TxData.FragmentCount = 1;\r
+          pTxData->TxData.FragmentTable[0].FragmentLength = (UINT32) BufferLength;\r
+          pTxData->TxData.FragmentTable[0].FragmentBuffer = &pPacket->Op.Udp4Tx.Buffer[0];\r
+\r
+          //\r
+          //  Set the remote system address if necessary\r
+          //\r
+          if ( NULL != pAddress ) {\r
+            pRemoteAddress = (const struct sockaddr_in *)pAddress;\r
+            pTxData->Session.SourceAddress.Addr[0] = 0;\r
+            pTxData->Session.SourceAddress.Addr[1] = 0;\r
+            pTxData->Session.SourceAddress.Addr[2] = 0;\r
+            pTxData->Session.SourceAddress.Addr[3] = 0;\r
+            pTxData->Session.SourcePort = 0;\r
+            pTxData->Session.DestinationAddress.Addr[0] = (UINT8)pRemoteAddress->sin_addr.s_addr;\r
+            pTxData->Session.DestinationAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );\r
+            pTxData->Session.DestinationAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );\r
+            pTxData->Session.DestinationAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );\r
+            pTxData->Session.DestinationPort = SwapBytes16 ( pRemoteAddress->sin_port );\r
+\r
+            //\r
+            //  Use the remote system address when sending this packet\r
+            //\r
+            pTxData->TxData.UdpSessionData = &pTxData->Session;\r
+          }\r
+\r
+          //\r
+          //  Copy the data into the buffer\r
+          //\r
+          CopyMem ( &pPacket->Op.Udp4Tx.Buffer[0],\r
+                    pBuffer,\r
+                    BufferLength );\r
+\r
+          //\r
+          //  Synchronize with the socket layer\r
+          //\r
+          RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+\r
+          //\r
+          //  Stop transmission after an error\r
+          //\r
+          if ( !EFI_ERROR ( pSocket->TxError )) {\r
+            //\r
+            //  Display the request\r
+            //\r
+            DEBUG (( DEBUG_TX,\r
+                      "Send %d %s bytes from 0x%08x\r\n",\r
+                      BufferLength,\r
+                      pBuffer ));\r
+\r
+            //\r
+            //  Queue the data for transmission\r
+            //\r
+            pPacket->pNext = NULL;\r
+            pPreviousPacket = pSocket->pTxPacketListTail;\r
+            if ( NULL == pPreviousPacket ) {\r
+              pSocket->pTxPacketListHead = pPacket;\r
+            }\r
+            else {\r
+              pPreviousPacket->pNext = pPacket;\r
+            }\r
+            pSocket->pTxPacketListTail = pPacket;\r
+            DEBUG (( DEBUG_TX,\r
+                      "0x%08x: Packet on transmit list\r\n",\r
+                      pPacket ));\r
+\r
+            //\r
+            //  Account for the buffered data\r
+            //\r
+            *pTxBytes += BufferLength;\r
+            *pDataLength = BufferLength;\r
+\r
+            //\r
+            //  Start the transmit engine if it is idle\r
+            //\r
+            if ( NULL == pUdp4->pTxPacket ) {\r
+              EslUdpTxStart4 ( pSocket->pPortList );\r
+            }\r
+          }\r
+          else {\r
+            //\r
+            //  Previous transmit error\r
+            //  Stop transmission\r
+            //\r
+            Status = pSocket->TxError;\r
+            pSocket->errno = EIO;\r
+\r
+            //\r
+            //  Free the packet\r
+            //\r
+            EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+          }\r
+\r
+          //\r
+          //  Release the socket layer synchronization\r
+          //\r
+          RESTORE_TPL ( TplPrevious );\r
+        }\r
+        else {\r
+          //\r
+          //  Packet allocation failed\r
+          //\r
+          pSocket->errno = ENOMEM;\r
+        }\r
+      }\r
+      else {\r
+        //\r
+        //  Not enough buffer space available\r
+        //\r
+        pSocket->errno = EAGAIN;\r
+        Status = EFI_NOT_READY;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Process the transmit completion\r
+\r
+  @param  Event         The normal transmit completion event\r
+\r
+  @param  pPort         The DT_PORT structure address\r
+\r
+**/\r
+VOID\r
+EslUdpTxComplete4 (\r
+  IN EFI_EVENT Event,\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  UINT32 LengthInBytes;\r
+  DT_PACKET * pCurrentPacket;\r
+  DT_PACKET * pNextPacket;\r
+  DT_PACKET * pPacket;\r
+  DT_SOCKET * pSocket;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_STATUS Status;\r
+  \r
+  DBG_ENTER ( );\r
+  \r
+  //\r
+  //  Locate the active transmit packet\r
+  //\r
+  pSocket = pPort->pSocket;\r
+  pUdp4 = &pPort->Context.Udp4;\r
+  pPacket = pUdp4->pTxPacket;\r
+  \r
+  //\r
+  //  Mark this packet as complete\r
+  //\r
+  pUdp4->pTxPacket = NULL;\r
+  LengthInBytes = pPacket->Op.Udp4Tx.TxData.DataLength;\r
+  pSocket->TxBytes -= LengthInBytes;\r
+  \r
+  //\r
+  //  Save any transmit error\r
+  //\r
+  Status = pUdp4->TxToken.Status;\r
+  if ( EFI_ERROR ( Status )) {\r
+    if ( !EFI_ERROR ( pSocket->TxError )) {\r
+      pSocket->TxError = Status;\r
+    }\r
+    DEBUG (( DEBUG_TX | DEBUG_INFO,\r
+              "ERROR - Transmit failure for packet 0x%08x, Status: %r\r\n",\r
+              pPacket,\r
+              Status ));\r
+  \r
+    //\r
+    //  Empty the normal transmit list\r
+    //\r
+    pCurrentPacket = pPacket;\r
+    pNextPacket = pSocket->pTxPacketListHead;\r
+    while ( NULL != pNextPacket ) {\r
+      pPacket = pNextPacket;\r
+      pNextPacket = pPacket->pNext;\r
+      EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+    }\r
+    pSocket->pTxPacketListHead = NULL;\r
+    pSocket->pTxPacketListTail = NULL;\r
+    pPacket = pCurrentPacket;\r
+  }\r
+  else\r
+  {\r
+    DEBUG (( DEBUG_TX | DEBUG_INFO,\r
+              "0x%08x: Packet transmitted %d bytes successfully\r\n",\r
+              pPacket,\r
+              LengthInBytes ));\r
+  \r
+    //\r
+    //  Verify the transmit engine is still running\r
+    //\r
+    if ( !pPort->bCloseNow ) {\r
+      //\r
+      //  Start the next packet transmission\r
+      //\r
+      EslUdpTxStart4 ( pPort );\r
+    }\r
+  }\r
+  \r
+  //\r
+  //  Release this packet\r
+  //\r
+  EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+  \r
+  //\r
+  //  Finish the close operation if necessary\r
+  //\r
+  if (( PORT_STATE_CLOSE_STARTED <= pPort->State )\r
+    && ( NULL == pSocket->pTxPacketListHead )\r
+    && ( NULL == pUdp4->pTxPacket )) {\r
+    //\r
+    //  Indicate that the transmit is complete\r
+    //\r
+    EslUdpPortCloseTxDone4 ( pPort );\r
+  }\r
+  DBG_EXIT ( );\r
+}\r
+\r
+\r
+/**\r
+  Transmit data using a network connection.\r
+\r
+  @param [in] pPort           Address of a DT_PORT structure\r
+\r
+ **/\r
+VOID\r
+EslUdpTxStart4 (\r
+  IN DT_PORT * pPort\r
+  )\r
+{\r
+  DT_PACKET * pNextPacket;\r
+  DT_PACKET * pPacket;\r
+  DT_SOCKET * pSocket;\r
+  DT_UDP4_CONTEXT * pUdp4;\r
+  EFI_UDP4_PROTOCOL * pUdp4Protocol;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Get the packet from the queue head\r
+  //\r
+  pSocket = pPort->pSocket;\r
+  pPacket = pSocket->pTxPacketListHead;\r
+  if ( NULL != pPacket ) {\r
+    //\r
+    //  Remove the packet from the queue\r
+    //\r
+    pNextPacket = pPacket->pNext;\r
+    pSocket->pTxPacketListHead = pNextPacket;\r
+    if ( NULL == pNextPacket ) {\r
+      pSocket->pTxPacketListTail = NULL;\r
+    }\r
+\r
+    //\r
+    //  Set the packet as active\r
+    //\r
+    pUdp4 = &pPort->Context.Udp4;\r
+    pUdp4->pTxPacket = pPacket;\r
+\r
+    //\r
+    //  Start the transmit operation\r
+    //\r
+    pUdp4Protocol = pUdp4->pProtocol;\r
+    pUdp4->TxToken.Packet.TxData = &pPacket->Op.Udp4Tx.TxData;\r
+    Status = pUdp4Protocol->Transmit ( pUdp4Protocol, &pUdp4->TxToken );\r
+    if ( EFI_ERROR ( Status )) {\r
+      pSocket = pPort->pSocket;\r
+      if ( EFI_SUCCESS == pSocket->TxError ) {\r
+        pSocket->TxError = Status;\r
+      }\r
+    }\r
+  }\r
+\r
+  DBG_EXIT ( );\r
+}\r
+\r
diff --git a/StdLib/EfiSocketLib/UseEfiSocketLib.c b/StdLib/EfiSocketLib/UseEfiSocketLib.c
new file mode 100644 (file)
index 0000000..b0e8ef6
--- /dev/null
@@ -0,0 +1,242 @@
+/** @file\r
+  Implement the connection to the EFI socket library\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <socket.h>\r
+\r
+\r
+CONST EFI_GUID mEslRawServiceGuid = {\r
+  0xc31bf4a5, 0x2c7, 0x49d2, { 0xa5, 0x58, 0xfe, 0x62, 0x6f, 0x7e, 0xd4, 0x77 }\r
+};\r
+\r
+CONST EFI_GUID mEslTcp4ServiceGuid = {\r
+  0xffc659c2, 0x4ef2, 0x4532, { 0xb8, 0x75, 0xcd, 0x9a, 0xa4, 0x27, 0x4c, 0xde }\r
+};\r
+\r
+CONST EFI_GUID mEslUdp4ServiceGuid = {\r
+  0x44e03a55, 0x8d97, 0x4511, { 0xbf, 0xef, 0xa, 0x8b, 0xc6, 0x2c, 0x25, 0xae }\r
+};\r
+\r
+\r
+/**\r
+  Connect to the EFI socket library\r
+\r
+  @param [in] ppSocketProtocol  Address to receive the socket protocol address\r
+\r
+  @retval 0             Successfully returned the socket protocol\r
+  @retval other         Value for errno\r
+ **/\r
+int\r
+EslServiceGetProtocol (\r
+  IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol\r
+  )\r
+{\r
+  EFI_HANDLE ChildHandle;\r
+  DT_SOCKET * pSocket;\r
+  int RetVal;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  RetVal = 0;\r
+\r
+  //\r
+  //  Locate the socket protocol\r
+  //\r
+  ChildHandle = NULL;\r
+  Status = EslSocketAllocate ( &ChildHandle,\r
+                               DEBUG_SOCKET,\r
+                               &pSocket );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    *ppSocketProtocol = &pSocket->SocketProtocol;\r
+  }\r
+  else {\r
+    //\r
+    //  No resources\r
+    //\r
+    RetVal = ENOMEM;\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DBG_EXIT_DEC ( RetVal );\r
+  return RetVal;\r
+}\r
+\r
+\r
+/**\r
+  Connect to the network layer\r
+\r
+  @retval EFI_SUCCESS   Successfully connected to the network layer\r
+\r
+ **/\r
+EFI_STATUS\r
+EslServiceNetworkConnect (\r
+  VOID\r
+  )\r
+{\r
+  UINTN HandleCount;\r
+  EFI_HANDLE * pHandles;\r
+  UINTN Index;\r
+  CONST DT_SOCKET_BINDING * pSocketBinding;\r
+  CONST DT_SOCKET_BINDING * pEnd;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Initialize the socket layer\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  EslServiceLoad ( gImageHandle );\r
+\r
+  //\r
+  //  Connect the network devices\r
+  //\r
+  pSocketBinding = &cEslSocketBinding [0];\r
+  pEnd = &pSocketBinding [ cEslSocketBindingEntries ];\r
+  while ( pEnd > pSocketBinding ) {\r
+    //\r
+    //  Attempt to locate the network adapters\r
+    //\r
+    HandleCount = 0;\r
+    pHandles = NULL;\r
+    Status = gBS->LocateHandleBuffer ( ByProtocol,\r
+                                       pSocketBinding->pNetworkBinding,\r
+                                       NULL,\r
+                                       &HandleCount,\r
+                                       &pHandles );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+    if ( NULL != pHandles ) {\r
+      //\r
+      //  Attempt to connect to this network adapter\r
+      //\r
+      for ( Index = 0; HandleCount > Index; Index++ ) {\r
+        Status = EslServiceConnect ( gImageHandle,\r
+                                     pHandles [ Index ]);\r
+        if ( EFI_ERROR ( Status )) {\r
+          break;\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Done with the handles\r
+      //\r
+      gBS->FreePool ( pHandles );\r
+    }\r
+\r
+    //\r
+    //  Set the next network protocol\r
+    //\r
+    pSocketBinding += 1;\r
+  }\r
+\r
+  //\r
+  //  Return the network connection status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Disconnect from the network layer\r
+\r
+  @retval EFI_SUCCESS   Successfully disconnected from the network layer\r
+\r
+ **/\r
+EFI_STATUS\r
+EslServiceNetworkDisconnect (\r
+  VOID\r
+  )\r
+{\r
+  UINTN HandleCount;\r
+  EFI_HANDLE * pHandles;\r
+  UINTN Index;\r
+  CONST DT_SOCKET_BINDING * pSocketBinding;\r
+  CONST DT_SOCKET_BINDING * pEnd;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Disconnect the network devices\r
+  //\r
+  pSocketBinding = &cEslSocketBinding [0];\r
+  pEnd = &pSocketBinding [ cEslSocketBindingEntries ];\r
+  while ( pEnd > pSocketBinding ) {\r
+    //\r
+    //  Attempt to locate the network adapters\r
+    //\r
+    HandleCount = 0;\r
+    pHandles = NULL;\r
+    Status = gBS->LocateHandleBuffer ( ByProtocol,\r
+                                       pSocketBinding->pNetworkBinding,\r
+                                       NULL,\r
+                                       &HandleCount,\r
+                                       &pHandles );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+    if ( NULL != pHandles ) {\r
+      //\r
+      //  Attempt to disconnect from this network adapter\r
+      //\r
+      for ( Index = 0; HandleCount > Index; Index++ ) {\r
+        Status = EslServiceDisconnect ( gImageHandle,\r
+                                        pHandles [ Index ]);\r
+        if ( EFI_ERROR ( Status )) {\r
+          break;\r
+        }\r
+      }\r
+\r
+      //\r
+      //  Done with the handles\r
+      //\r
+      gBS->FreePool ( pHandles );\r
+    }\r
+\r
+    //\r
+    //  Set the next network protocol\r
+    //\r
+    pSocketBinding += 1;\r
+  }\r
+\r
+  //\r
+  //  Finish the disconnect operation\r
+  //\r
+  if ( !EFI_ERROR ( Status )) {\r
+    EslServiceUnload ( );\r
+  }\r
+\r
+  //\r
+  //  Return the network connection status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+PFN_ESL_xSTRUCTOR mpfnEslConstructor = EslServiceNetworkConnect;\r
+PFN_ESL_xSTRUCTOR mpfnEslDestructor = EslServiceNetworkDisconnect;\r
diff --git a/StdLib/Include/Efi/EfiSocketLib.h b/StdLib/Include/Efi/EfiSocketLib.h
new file mode 100644 (file)
index 0000000..53ad0d4
--- /dev/null
@@ -0,0 +1,679 @@
+/** @file\r
+  Definitions for the EFI Socket layer library.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _EFI_SOCKET_LIB_H_\r
+#define _EFI_SOCKET_LIB_H_\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <Protocol/EfiSocket.h>\r
+#include <Protocol/ServiceBinding.h>\r
+#include <Protocol/Tcp4.h>\r
+#include <Protocol/Udp4.h>\r
+\r
+#include <sys/time.h>\r
+\r
+//------------------------------------------------------------------------------\r
+//  Constants\r
+//------------------------------------------------------------------------------\r
+\r
+#define DEBUG_TPL           0x40000000  ///<  Display TPL change messages\r
+\r
+#define TPL_SOCKETS     TPL_CALLBACK    ///<  TPL for routine synchronization\r
+\r
+//------------------------------------------------------------------------------\r
+//  Macros\r
+//------------------------------------------------------------------------------\r
+\r
+#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */\r
+#define DBG_ENTER()             DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry\r
+#define DBG_EXIT()              DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit\r
+#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value\r
+#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value\r
+#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value\r
+#define DBG_EXIT_TF(Status)     DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value\r
+#else   //  _MSC_VER\r
+#define DBG_ENTER()\r
+#define DBG_EXIT()\r
+#define DBG_EXIT_DEC(Status)\r
+#define DBG_EXIT_HEX(Status)\r
+#define DBG_EXIT_STATUS(Status)\r
+#define DBG_EXIT_TF(Status)\r
+#endif  //  _MSC_VER\r
+\r
+#define DIM(x)    ( sizeof ( x ) / sizeof ( x[0] ))   ///<  Compute the number of entries in an array\r
+\r
+/**\r
+  Verify new TPL value\r
+\r
+  This macro which is enabled when debug is enabled verifies that\r
+  the new TPL value is >= the current TPL value.\r
+**/\r
+#ifdef VERIFY_TPL\r
+#undef VERIFY_TPL\r
+#endif  //  VERIFY_TPL\r
+\r
+#if !defined(MDEPKG_NDEBUG)\r
+\r
+#define VERIFY_TPL(tpl)                           \\r
+{                                                 \\r
+  EFI_TPL PreviousTpl;                            \\r
+                                                  \\r
+  PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \\r
+  gBS->RestoreTPL ( PreviousTpl );                \\r
+  if ( PreviousTpl > tpl ) {                      \\r
+    DEBUG (( DEBUG_ERROR | DEBUG_TPL,             \\r
+              "Current TPL: %d, New TPL: %d\r\n", \\r
+              PreviousTpl, tpl ));                \\r
+    ASSERT ( PreviousTpl <= tpl );                \\r
+  }                                               \\r
+}\r
+\r
+#else   //  MDEPKG_NDEBUG\r
+\r
+#define VERIFY_TPL(tpl)\r
+\r
+#endif  //  MDEPKG_NDEBUG\r
+\r
+#define RAISE_TPL(PreviousTpl, tpl)     \\r
+  VERIFY_TPL ( tpl );                   \\r
+  PreviousTpl = gBS->RaiseTPL ( tpl );  \\r
+  DEBUG (( DEBUG_TPL | DEBUG_TPL,       \\r
+          "%d: TPL\r\n",                \\r
+          tpl ))\r
+\r
+#define RESTORE_TPL(tpl)            \\r
+  gBS->RestoreTPL ( tpl );          \\r
+  DEBUG (( DEBUG_TPL | DEBUG_TPL,   \\r
+          "%d: TPL\r\n",            \\r
+          tpl ))\r
+\r
+//------------------------------------------------------------------------------\r
+// Data Types\r
+//------------------------------------------------------------------------------\r
+\r
+typedef struct _DT_SERVICE DT_SERVICE;  ///<  Forward delcaration\r
+\r
+typedef\r
+EFI_STATUS\r
+(* PFN_SB_INITIALIZE) (\r
+    DT_SERVICE * pService\r
+    );\r
+\r
+typedef\r
+VOID\r
+(* PFN_SB_SHUTDOWN) (\r
+    DT_SERVICE * pService\r
+    );\r
+\r
+/**\r
+  Protocol binding and installation control structure\r
+\r
+  The driver uses this structure to simplify the driver binding processing.\r
+**/\r
+typedef struct {\r
+  CHAR16 * pName;                 ///<  Protocol name\r
+  EFI_GUID * pNetworkBinding;     ///<  Network service binding protocol for socket support\r
+  CONST EFI_GUID * pTagGuid;      ///<  Tag to mark protocol in use\r
+  PFN_SB_INITIALIZE pfnInitialize;///<  Routine to initialize the service\r
+  PFN_SB_SHUTDOWN pfnShutdown;    ///<  Routine to shutdown the service\r
+} DT_SOCKET_BINDING;\r
+\r
+//------------------------------------------------------------------------------\r
+// GUIDs\r
+//------------------------------------------------------------------------------\r
+\r
+extern CONST EFI_GUID mEslRawServiceGuid;\r
+extern CONST EFI_GUID mEslTcp4ServiceGuid;\r
+extern CONST EFI_GUID mEslUdp4ServiceGuid;\r
+\r
+//------------------------------------------------------------------------------\r
+// Data\r
+//------------------------------------------------------------------------------\r
+\r
+extern CONST DT_SOCKET_BINDING cEslSocketBinding [];\r
+extern CONST UINTN cEslSocketBindingEntries;\r
+\r
+//------------------------------------------------------------------------------\r
+// Service Support Routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Connect to the network service bindings\r
+\r
+  Walk the network service protocols on the controller handle and\r
+  locate any that are not in use.  Create service structures to\r
+  manage the service binding for the socket driver.\r
+\r
+  @param [in] BindingHandle    Handle for protocol binding.\r
+  @param [in] Controller       Handle of device to work with.\r
+\r
+  @retval EFI_SUCCESS          This driver is added to Controller.\r
+  @retval other                This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslServiceConnect (\r
+  IN EFI_HANDLE BindingHandle,\r
+  IN EFI_HANDLE Controller\r
+  );\r
+\r
+/**\r
+  Shutdown the network connections to this controller by removing\r
+  NetworkInterfaceIdentifier protocol and closing the DevicePath\r
+  and PciIo protocols on Controller.\r
+\r
+  @param [in] BindingHandle    Handle for protocol binding.\r
+  @param [in] Controller           Handle of device to stop driver on.\r
+\r
+  @retval EFI_SUCCESS          This driver is removed Controller.\r
+  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.\r
+  @retval other                This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslServiceDisconnect (\r
+  IN  EFI_HANDLE BindingHandle,\r
+  IN  EFI_HANDLE Controller\r
+  );\r
+\r
+/**\r
+Install the socket service\r
+\r
+@param [in] pImageHandle      Address of the image handle\r
+\r
+@retval EFI_SUCCESS     Service installed successfully\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslServiceInstall (\r
+  IN EFI_HANDLE * pImageHandle\r
+  );\r
+\r
+/**\r
+Initialize the service layer\r
+\r
+@param [in] ImageHandle       Handle for the image.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EslServiceLoad (\r
+  IN EFI_HANDLE ImageHandle\r
+  );\r
+\r
+/**\r
+Uninstall the socket service\r
+\r
+@param [in] ImageHandle       Handle for the image.\r
+\r
+@retval EFI_SUCCESS     Service installed successfully\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslServiceUninstall (\r
+  IN EFI_HANDLE ImageHandle\r
+  );\r
+\r
+/**\r
+  Shutdown the service layer\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EslServiceUnload (\r
+  VOID\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+// Socket Service Binding Protocol Routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Creates a child handle and installs a protocol.\r
+\r
+  The CreateChild() function installs a protocol on ChildHandle.\r
+  If pChildHandle is a pointer to NULL, then a new handle is created and returned in pChildHandle.\r
+  If pChildHandle is not a pointer to NULL, then the protocol installs on the existing pChildHandle.\r
+\r
+  @param [in] pThis        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+  @param [in] pChildHandle Pointer to the handle of the child to create. If it is NULL,\r
+                           then a new handle is created. If it is a pointer to an existing UEFI handle,\r
+                           then the protocol is added to the existing UEFI handle.\r
+\r
+  @retval EFI_SUCCES            The protocol was added to ChildHandle.\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources availabe to create\r
+                                the child\r
+  @retval other                 The child handle was not created\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslSocketCreateChild (\r
+  IN     EFI_SERVICE_BINDING_PROTOCOL * pThis,\r
+  IN OUT EFI_HANDLE * pChildHandle\r
+  );\r
+\r
+/**\r
+  Destroys a child handle with a protocol installed on it.\r
+\r
+  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
+  that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
+  last protocol on ChildHandle, then ChildHandle is destroyed.\r
+\r
+  @param [in] pThis       Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+  @param [in] ChildHandle Handle of the child to destroy\r
+\r
+  @retval EFI_SUCCES            The protocol was removed from ChildHandle.\r
+  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.\r
+  @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.\r
+  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle\r
+                                because its services are being used.\r
+  @retval other                 The child handle was not destroyed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EslSocketDestroyChild (\r
+  IN EFI_SERVICE_BINDING_PROTOCOL * pThis,\r
+  IN EFI_HANDLE ChildHandle\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+// Socket Protocol Routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Bind a name to a socket.\r
+\r
+  The ::SocketBind routine connects a name to a socket on the local machine.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html">POSIX</a>\r
+  documentation for the bind routine is available online for reference.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] pSockAddr Address of a sockaddr structure that contains the\r
+                        connection point on the local machine.  An IPv4 address\r
+                        of INADDR_ANY specifies that the connection is made to\r
+                        all of the network stacks on the platform.  Specifying a\r
+                        specific IPv4 address restricts the connection to the\r
+                        network stack supporting that address.  Specifying zero\r
+                        for the port causes the network layer to assign a port\r
+                        number from the dynamic range.  Specifying a specific\r
+                        port number causes the network layer to use that port.\r
+\r
+  @param [in] SockAddrLen   Specifies the length in bytes of the sockaddr structure.\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketBind (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength,\r
+  OUT int * pErrno\r
+  );\r
+\r
+/**\r
+  Determine if the socket is closed\r
+\r
+  Reverses the operations of the ::SocketAllocate() routine.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS     Socket successfully closed\r
+  @retval EFI_NOT_READY   Close still in progress\r
+  @retval EFI_ALREADY     Close operation already in progress\r
+  @retval Other           Failed to close the socket\r
+\r
+**/\r
+EFI_STATUS\r
+EslSocketClosePoll (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Start the close operation on the socket\r
+\r
+  Start closing the socket by closing all of the ports.  Upon\r
+  completion, the ::SocketPoll() routine finishes closing the\r
+  socket.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [in] bCloseNow       Boolean to control close behavior\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS     Socket successfully closed\r
+  @retval EFI_NOT_READY   Close still in progress\r
+  @retval EFI_ALREADY     Close operation already in progress\r
+  @retval Other           Failed to close the socket\r
+\r
+**/\r
+EFI_STATUS\r
+EslSocketCloseStart (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN BOOLEAN bCloseNow,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Connect to a remote system via the network.\r
+\r
+  The ::SocketConnect routine attempts to establish a connection to a\r
+  socket on the local or remote system using the specified address.\r
+  The POSIX\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html">connect</a>\r
+  documentation is available online.\r
+\r
+  There are three states associated with a connection:\r
+  <ul>\r
+    <li>Not connected</li>\r
+    <li>Connection in progress</li>\r
+    <li>Connected</li>\r
+  </ul>\r
+  In the "Not connected" state, calls to ::connect start the connection\r
+  processing and update the state to "Connection in progress".  During\r
+  the "Connection in progress" state, connect polls for connection completion\r
+  and moves the state to "Connected" after the connection is established.\r
+  Note that these states are only visible when the file descriptor is marked\r
+  with O_NONBLOCK.  Also, the POLL_WRITE bit is set when the connection\r
+  completes and may be used by poll or select as an indicator to call\r
+  connect again.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] pSockAddr       Network address of the remote system.\r
+\r
+  @param [in] SockAddrLength  Length in bytes of the network address.\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketConnect (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Get the local address.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [out] pAddress       Network address to receive the local system address\r
+\r
+  @param [in,out] pAddressLength  Length of the local network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Local address successfully returned\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketGetLocalAddress (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Get the peer address.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Remote address successfully returned\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketGetPeerAddress (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Establish the known port to listen for network connections.\r
+\r
+  The ::SocketListen routine places the port into a state that enables connection\r
+  attempts.  Connections are placed into FIFO order in a queue to be serviced\r
+  by the application.  The application calls the ::SocketAccept routine to remove\r
+  the next connection from the queue and get the associated socket.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html">POSIX</a>\r
+  documentation for the bind routine is available online for reference.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] Backlog         Backlog specifies the maximum FIFO depth for\r
+                              the connections waiting for the application\r
+                              to call accept.  Connection attempts received\r
+                              while the queue is full are refused.\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+  @retval Other - Failed to enable the socket for listen\r
+\r
+**/\r
+EFI_STATUS\r
+EslSocketListen (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN INT32 Backlog,\r
+  OUT int * pErrno\r
+  );\r
+\r
+/**\r
+  Get the socket options\r
+\r
+  Retrieve the socket options one at a time by name.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [in] level           Option protocol level\r
+  @param [in] option_name     Name of the option\r
+  @param [out] option_value   Buffer to receive the option value\r
+  @param [in,out] option_len  Length of the buffer in bytes,\r
+                              upon return length of the option value in bytes\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketOptionGet (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int level,\r
+  IN int option_name,\r
+  OUT void * __restrict option_value,\r
+  IN OUT socklen_t * __restrict option_len,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Set the socket options\r
+\r
+  Adjust the socket options one at a time by name.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [in] level           Option protocol level\r
+  @param [in] option_name     Name of the option\r
+  @param [in] option_value    Buffer containing the option value\r
+  @param [in] option_len      Length of the buffer in bytes\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketOptionSet (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int level,\r
+  IN int option_name,\r
+  IN CONST void * option_value,\r
+  IN socklen_t option_len,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Poll a socket for pending activity.\r
+\r
+  The SocketPoll routine checks a socket for pending activity associated\r
+  with the event mask.  Activity is returned in the detected event buffer.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] Events    Events of interest for this socket\r
+\r
+  @param [in] pEvents   Address to receive the detected events\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully polled\r
+  @retval EFI_INVALID_PARAMETER - When pEvents is NULL\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketPoll (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN short Events,\r
+  IN short * pEvents,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Receive data from a network connection.\r
+\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] Flags           Message control flags\r
+\r
+  @param [in] BufferLength    Length of the the buffer\r
+\r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+\r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketReceive (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN INT32 Flags,\r
+  IN size_t BufferLength,\r
+  IN UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Shutdown the socket receive and transmit operations\r
+\r
+  The SocketShutdown routine stops the socket receive and transmit\r
+  operations.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] How             Which operations to stop\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket operations successfully shutdown\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketShutdown (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int How,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Send data using a network connection.\r
+\r
+  The SocketTransmit routine queues the data for transmission to the\r
+  remote network connection.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] Flags           Message control flags\r
+\r
+  @param [in] BufferLength    Length of the the buffer\r
+\r
+  @param [in] pBuffer         Address of a buffer containing the data to send\r
+\r
+  @param [in] pDataLength     Address to receive the number of data bytes sent\r
+\r
+  @param [in] pAddress        Network address of the remote system address\r
+\r
+  @param [in] AddressLength   Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+EFI_STATUS\r
+EslSocketTransmit (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int Flags,\r
+  IN size_t BufferLength,\r
+  IN CONST UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  IN const struct sockaddr * pAddress,\r
+  IN socklen_t AddressLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+#endif  //  _EFI_SOCKET_LIB_H_\r
index 62fbe40b4204b5d05e5b30cbd03002c8baa38d1c..0b3cfbe4c5eb01906ad8a3181cda296761e7468d 100644 (file)
@@ -1,3 +1,14 @@
 #include  <x86/limits.h>\r
 \r
 #define __POINTER_BIT   32\r
+#define __LONG_BIT      32\r
+\r
+/** minimum value for an object of type long int **/\r
+#define __LONG_MIN    (-2147483647L - 1L) // -(2^31 - 1)\r
+\r
+/** maximum value for an object of type long int **/\r
+#define __LONG_MAX    +2147483647L // 2^31 - 1\r
+\r
+/** maximum value for an object of type unsigned long int **/\r
+#define __ULONG_MAX   0xffffffff // 2^32 - 1\r
+\r
diff --git a/StdLib/Include/Protocol/EfiSocket.h b/StdLib/Include/Protocol/EfiSocket.h
new file mode 100644 (file)
index 0000000..5e044fa
--- /dev/null
@@ -0,0 +1,606 @@
+/** @file\r
+  Definitions for the EFI Socket protocol.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _EFI_SOCKET_H_\r
+#define _EFI_SOCKET_H_\r
+\r
+#include <errno.h>\r
+#include <Uefi.h>\r
+\r
+#include <netinet/in.h>\r
+\r
+#include <sys/poll.h>\r
+#include <sys/socket.h>\r
+\r
+//------------------------------------------------------------------------------\r
+//  Data Types\r
+//------------------------------------------------------------------------------\r
+\r
+typedef struct _EFI_SOCKET_PROTOCOL EFI_SOCKET_PROTOCOL;\r
+\r
+/**\r
+  Constructor/Destructor\r
+\r
+  @retval EFI_SUCCESS       The operation was successful\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_ESL_xSTRUCTOR) (\r
+  VOID\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+// Data\r
+//------------------------------------------------------------------------------\r
+\r
+extern PFN_ESL_xSTRUCTOR mpfnEslConstructor;\r
+extern PFN_ESL_xSTRUCTOR mpfnEslDestructor;\r
+\r
+extern EFI_GUID  gEfiSocketProtocolGuid;\r
+extern EFI_GUID  gEfiSocketServiceBindingProtocolGuid;\r
+\r
+//------------------------------------------------------------------------------\r
+//  Socket API\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Accept a network connection.\r
+\r
+  The SocketAccept routine waits for a network connection to the socket.\r
+  It is able to return the remote network address to the caller if\r
+  requested.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] pSockAddr       Address of a buffer to receive the remote\r
+                              network address.\r
+\r
+  @param [in, out] pSockAddrLength  Length in bytes of the address buffer.\r
+                                    On output specifies the length of the\r
+                                    remote network address.\r
+\r
+  @param [out] ppSocketProtocol Address of a buffer to receive the socket protocol\r
+                                instance associated with the new socket.\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS   New connection successfully created\r
+  @retval EFI_NOT_READY No connection is available\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_ACCEPT) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN struct sockaddr * pSockAddr,\r
+  IN OUT socklen_t * pSockAddrLength,\r
+  IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Bind a name to a socket.\r
+\r
+  The ::SocketBind routine connects a name to a socket on the local machine.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html">POSIX</a>\r
+  documentation for the bind routine is available online for reference.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] pSockAddr Address of a sockaddr structure that contains the\r
+                        connection point on the local machine.  An IPv4 address\r
+                        of INADDR_ANY specifies that the connection is made to\r
+                        all of the network stacks on the platform.  Specifying a\r
+                        specific IPv4 address restricts the connection to the\r
+                        network stack supporting that address.  Specifying zero\r
+                        for the port causes the network layer to assign a port\r
+                        number from the dynamic range.  Specifying a specific\r
+                        port number causes the network layer to use that port.\r
+\r
+  @param [in] SockAddrLen   Specifies the length in bytes of the sockaddr structure.\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_BIND) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength,\r
+  OUT int * pErrno\r
+  );\r
+\r
+/**\r
+  Determine if the socket is closed\r
+\r
+  Reverses the operations of the ::SocketAllocate() routine.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS     Socket successfully closed\r
+  @retval EFI_NOT_READY   Close still in progress\r
+  @retval EFI_ALREADY     Close operation already in progress\r
+  @retval Other           Failed to close the socket\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_CLOSE_POLL) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Start the close operation on the socket\r
+\r
+  Start closing the socket by closing all of the ports.  Upon\r
+  completion, the ::pfnClosePoll() routine finishes closing the\r
+  socket.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [in] bCloseNow       Boolean to control close behavior\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS     Socket successfully closed\r
+  @retval EFI_NOT_READY   Close still in progress\r
+  @retval EFI_ALREADY     Close operation already in progress\r
+  @retval Other           Failed to close the socket\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_CLOSE_START) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN BOOLEAN bCloseNow,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Connect to a remote system via the network.\r
+\r
+  The ::Connect routine attempts to establish a connection to a\r
+  socket on the local or remote system using the specified address.\r
+  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  There are three states associated with a connection:\r
+  <ul>\r
+    <li>Not connected</li>\r
+    <li>Connection in progress</li>\r
+    <li>Connected</li>\r
+  </ul>\r
+  In the "Not connected" state, calls to ::connect start the connection\r
+  processing and update the state to "Connection in progress".  During\r
+  the "Connection in progress" state, connect polls for connection completion\r
+  and moves the state to "Connected" after the connection is established.\r
+  Note that these states are only visible when the file descriptor is marked\r
+  with O_NONBLOCK.  Also, the POLL_WRITE bit is set when the connection\r
+  completes and may be used by poll or select as an indicator to call\r
+  connect again.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] pSockAddr       Network address of the remote system.\r
+    \r
+  @param [in] SockAddrLength  Length in bytes of the network address.\r
+  \r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+  \r
+  @retval EFI_SUCCESS   The connection was successfully established.\r
+  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
+  @retval Others        The connection attempt failed.\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_CONNECT) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN const struct sockaddr * pSockAddr,\r
+  IN socklen_t SockAddrLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Get the local address.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [out] pAddress       Network address to receive the local system address\r
+\r
+  @param [in,out] pAddressLength  Length of the local network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Local address successfully returned\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_GET_LOCAL) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Get the peer address.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Remote address successfully returned\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_GET_PEER) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Establish the known port to listen for network connections.\r
+\r
+  The ::SocketAisten routine places the port into a state that enables connection\r
+  attempts.  Connections are placed into FIFO order in a queue to be serviced\r
+  by the application.  The application calls the ::SocketAccept routine to remove\r
+  the next connection from the queue and get the associated socket.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html">POSIX</a>\r
+  documentation for the bind routine is available online for reference.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] Backlog         Backlog specifies the maximum FIFO depth for\r
+                              the connections waiting for the application\r
+                              to call accept.  Connection attempts received\r
+                              while the queue is full are refused.\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+  @retval Other - Failed to enable the socket for listen\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_LISTEN) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN INT32 Backlog,\r
+  OUT int * pErrno\r
+  );\r
+\r
+/**\r
+  Get the socket options\r
+\r
+  Retrieve the socket options one at a time by name.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] pSocketProtocol   Address of the socket protocol structure.\r
+  @param [in] level             Option protocol level\r
+  @param [in] OptionName        Name of the option\r
+  @param [out] pOptionValue     Buffer to receive the option value\r
+  @param [in,out] pOptionLength Length of the buffer in bytes,\r
+                                upon return length of the option value in bytes\r
+  @param [out] pErrno           Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_OPTION_GET) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int level,\r
+  IN int OptionName,\r
+  OUT void * __restrict pOptionValue,\r
+  IN OUT socklen_t * __restrict pOptionLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Set the socket options\r
+\r
+  Adjust the socket options one at a time by name.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  @param [in] level           Option protocol level\r
+  @param [in] OptionName      Name of the option\r
+  @param [in] pOptionValue    Buffer containing the option value\r
+  @param [in] OptionLength    Length of the buffer in bytes\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_OPTION_SET) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int level,\r
+  IN int OptionName,\r
+  IN CONST void * pOptionValue,\r
+  IN socklen_t OptionLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Poll a socket for pending activity.\r
+\r
+  The SocketPoll routine checks a socket for pending activity associated\r
+  with the event mask.  Activity is returned in the detected event buffer.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] Events    Events of interest for this socket\r
+\r
+  @param [in] pEvents   Address to receive the detected events\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully polled\r
+  @retval EFI_INVALID_PARAMETER - When pEvents is NULL\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_POLL) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN short Events,\r
+  IN short * pEvents,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Receive data from a network connection.\r
+\r
+  The ::recv routine waits for receive data from a remote network\r
+  connection.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html">POSIX</a>\r
+  documentation is available online.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [in] Flags           Message control flags\r
+  \r
+  @param [in] BufferLength    Length of the the buffer\r
+  \r
+  @param [in] pBuffer         Address of a buffer to receive the data.\r
+  \r
+  @param [in] pDataLength     Number of received data bytes in the buffer.\r
+\r
+  @param [out] pAddress       Network address to receive the remote system address\r
+\r
+  @param [in,out] pAddressLength  Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully received\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_RECEIVE) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int Flags,\r
+  IN size_t BufferLength,\r
+  IN UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  OUT struct sockaddr * pAddress,\r
+  IN OUT socklen_t * pAddressLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Send data using a network connection.\r
+\r
+  The SocketTransmit routine queues the data for transmission to the\r
+  remote network connection.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [in] Flags           Message control flags\r
+  \r
+  @param [in] BufferLength    Length of the the buffer\r
+  \r
+  @param [in] pBuffer         Address of a buffer containing the data to send\r
+  \r
+  @param [in] pDataLength     Address to receive the number of data bytes sent\r
+\r
+  @param [in] pAddress        Network address of the remote system address\r
+\r
+  @param [in] AddressLength   Length of the remote network address structure\r
+\r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket data successfully queued for transmission\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_SEND) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int Flags,\r
+  IN size_t BufferLength,\r
+  IN CONST UINT8 * pBuffer,\r
+  OUT size_t * pDataLength,\r
+  IN const struct sockaddr * pAddress,\r
+  IN socklen_t AddressLength,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Shutdown the socket receive and transmit operations\r
+\r
+  The SocketShutdown routine stops the socket receive and transmit\r
+  operations.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+  \r
+  @param [in] How             Which operations to stop\r
+  \r
+  @param [out] pErrno         Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket operations successfully shutdown\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(* PFN_SHUTDOWN) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int How,\r
+  IN int * pErrno\r
+  );\r
+\r
+/**\r
+  Initialize an endpoint for network communication.\r
+\r
+  The ::Socket routine initializes the communication endpoint by providing\r
+  the support for the socket library function ::socket.  The\r
+  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html">POSIX</a>\r
+  documentation for the socket routine is available online for reference.\r
+\r
+  @param [in] pSocketProtocol Address of the socket protocol structure.\r
+\r
+  @param [in] domain    Select the family of protocols for the client or server\r
+                        application.\r
+\r
+  @param [in] type      Specifies how to make the network connection.  The following values\r
+                        are supported:\r
+                        <ul>\r
+                          <li>\r
+                            SOCK_STREAM - Connect to TCP, provides a byte stream\r
+                            that is manipluated by read, recv, send and write.\r
+                          </li>\r
+                          <li>\r
+                            SOCK_SEQPACKET - Connect to TCP, provides sequenced packet stream\r
+                            that is manipulated by read, recv, send and write.\r
+                          </li>\r
+                          <li>\r
+                            SOCK_DGRAM - Connect to UDP, provides a datagram service that is\r
+                            manipulated by recvfrom and sendto.\r
+                          </li>\r
+                        </ul>\r
+\r
+  @param [in] protocol  Specifies the lower layer protocol to use.  The following\r
+                        values are supported:\r
+                        <ul>\r
+                          <li>IPPROTO_TCP</li> - This value must be combined with SOCK_STREAM.</li>\r
+                          <li>IPPROTO_UDP</li> - This value must be combined with SOCK_DGRAM.</li>\r
+                        </ul>\r
+\r
+  @param [out] pErrno   Address to receive the errno value upon completion.\r
+\r
+  @retval EFI_SUCCESS - Socket successfully created\r
+  @retval EFI_INVALID_PARAMETER - Invalid domain value, errno = EAFNOSUPPORT\r
+  @retval EFI_INVALID_PARAMETER - Invalid type value, errno = EINVAL\r
+  @retval EFI_INVALID_PARAMETER - Invalid protocol value, errno = EINVAL\r
+\r
+ **/\r
+typedef\r
+EFI_STATUS\r
+(*PFN_SOCKET) (\r
+  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
+  IN int domain,\r
+  IN int type,\r
+  IN int protocol,\r
+  IN int * pErrno\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+//  Socket Protocol\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Socket protocol declaration\r
+**/\r
+typedef struct _EFI_SOCKET_PROTOCOL {\r
+  EFI_HANDLE SocketHandle;        ///<  Handle for the socket\r
+  PFN_ACCEPT pfnAccept;           ///<  Accept a network connection\r
+  PFN_BIND pfnBind;               ///<  Bind a local address to the socket\r
+  PFN_CLOSE_POLL pfnClosePoll;    ///<  Determine if the socket is closed\r
+  PFN_CLOSE_START pfnCloseStart;  ///<  Start the close operation\r
+  PFN_CONNECT pfnConnect;         ///<  Connect to a remote system\r
+  PFN_GET_LOCAL pfnGetLocal;      ///<  Get local address\r
+  PFN_GET_PEER pfnGetPeer;        ///<  Get peer address\r
+  PFN_LISTEN pfnListen;           ///<  Enable connection attempts on known port\r
+  PFN_POLL pfnPoll;               ///<  Poll for socket activity\r
+  PFN_OPTION_GET pfnOptionGet;    ///<  Get socket options\r
+  PFN_OPTION_SET pfnOptionSet;    ///<  Set socket options\r
+  PFN_RECEIVE pfnReceive;         ///<  Receive data from a socket\r
+  PFN_SEND pfnSend;               ///<  Transmit data using the socket\r
+  PFN_SHUTDOWN pfnShutdown;       ///<  Shutdown receive and transmit operations\r
+  PFN_SOCKET pfnSocket;           ///<  Initialize the socket\r
+} GCC_EFI_SOCKET_PROTOCOL;\r
+\r
+//------------------------------------------------------------------------------\r
+//  Non-blocking routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Non blocking version of accept.\r
+\r
+  See ::accept\r
+\r
+  @param [in] s         Socket file descriptor returned from ::socket.\r
+\r
+  @param [in] address   Address of a buffer to receive the remote network address.\r
+\r
+  @param [in, out] address_len  Address of a buffer containing the Length in bytes\r
+                                of the remote network address buffer.  Upon return,\r
+                                contains the length of the remote network address.\r
+\r
+  @returns    This routine returns zero if successful and -1 when an error occurs.\r
+              In the case of an error, errno contains more details.\r
+\r
+ **/\r
+int\r
+AcceptNB (\r
+  int s,\r
+  struct sockaddr * address,\r
+  socklen_t * address_len\r
+  );\r
+\r
+/**\r
+  Connect to the socket driver\r
+\r
+  @param [in] ppSocketProtocol  Address to receive the socket protocol address\r
+\r
+  @retval 0             Successfully returned the socket protocol\r
+  @retval other         Value for errno\r
+ **/\r
+int\r
+EslServiceGetProtocol (\r
+  IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+#endif  //  _EFI_SOCKET_H_\r
index 663b2e3290a9ab43f64647c990306a504d8721af..d046c64dabceb999f06d79381d822ebcab7844ab 100644 (file)
@@ -1,3 +1,25 @@
 #include  <x86/limits.h>\r
 \r
 #define __POINTER_BIT   64\r
+\r
+#if defined(__GNUC__)\r
+#define __LONG_BIT      64\r
+/** minimum value for an object of type long int **/\r
+#define __LONG_MIN    (-9223372036854775807L - 1L) // -(2^63 - 1)\r
+\r
+/** maximum value for an object of type long int **/\r
+#define __LONG_MAX    +9223372036854775807L // 2^63 - 1\r
+\r
+/** maximum value for an object of type unsigned long int **/\r
+#define __ULONG_MAX   0xFFFFFFFFFFFFFFFFUL // 2^64 - 1\r
+#else\r
+#define __LONG_BIT      32\r
+/** minimum value for an object of type long int **/\r
+#define __LONG_MIN    (-2147483647L - 1L) // -(2^31 - 1)\r
+\r
+/** maximum value for an object of type long int **/\r
+#define __LONG_MAX    +2147483647L // 2^31 - 1\r
+\r
+/** maximum value for an object of type unsigned long int **/\r
+#define __ULONG_MAX   0xffffffff // 2^32 - 1\r
+#endif\r
diff --git a/StdLib/Include/arpa/ftp.h b/StdLib/Include/arpa/ftp.h
new file mode 100644 (file)
index 0000000..3cb509d
--- /dev/null
@@ -0,0 +1,109 @@
+/*\r
+ * Copyright (c) 1983, 1989, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)ftp.h       8.1 (Berkeley) 6/2/93\r
+ */\r
+\r
+#ifndef _ARPA_FTP_H_\r
+#define        _ARPA_FTP_H_\r
+\r
+/* Definitions for FTP; see RFC-765. */\r
+\r
+/*\r
+ * Reply codes.\r
+ */\r
+#define PRELIM         1       /* positive preliminary */\r
+#define COMPLETE       2       /* positive completion */\r
+#define CONTINUE       3       /* positive intermediate */\r
+#define TRANSIENT      4       /* transient negative completion */\r
+#define ERROR          5       /* permanent negative completion */\r
+\r
+/*\r
+ * Type codes\r
+ */\r
+#define        TYPE_A          1       /* ASCII */\r
+#define        TYPE_E          2       /* EBCDIC */\r
+#define        TYPE_I          3       /* image */\r
+#define        TYPE_L          4       /* local byte size */\r
+\r
+#ifdef FTP_NAMES\r
+char *typenames[] =  {"0", "ASCII", "EBCDIC", "Image", "Local" };\r
+#endif\r
+\r
+/*\r
+ * Form codes\r
+ */\r
+#define        FORM_N          1       /* non-print */\r
+#define        FORM_T          2       /* telnet format effectors */\r
+#define        FORM_C          3       /* carriage control (ASA) */\r
+#ifdef FTP_NAMES\r
+char *formnames[] =  {"0", "Nonprint", "Telnet", "Carriage-control" };\r
+#endif\r
+\r
+/*\r
+ * Structure codes\r
+ */\r
+#define        STRU_F          1       /* file (no record structure) */\r
+#define        STRU_R          2       /* record structure */\r
+#define        STRU_P          3       /* page structure */\r
+#ifdef FTP_NAMES\r
+char *strunames[] =  {"0", "File", "Record", "Page" };\r
+#endif\r
+\r
+/*\r
+ * Mode types\r
+ */\r
+#define        MODE_S          1       /* stream */\r
+#define        MODE_B          2       /* block */\r
+#define        MODE_C          3       /* compressed */\r
+#ifdef FTP_NAMES\r
+char *modenames[] =  {"0", "Stream", "Block", "Compressed" };\r
+#endif\r
+\r
+/*\r
+ * Record Tokens\r
+ */\r
+#define        REC_ESC         '\377'  /* Record-mode Escape */\r
+#define        REC_EOR         '\001'  /* Record-mode End-of-Record */\r
+#define REC_EOF                '\002'  /* Record-mode End-of-File */\r
+\r
+/*\r
+ * Block Header\r
+ */\r
+#define        BLK_EOR         0x80    /* Block is End-of-Record */\r
+#define        BLK_EOF         0x40    /* Block is End-of-File */\r
+#define BLK_ERRORS     0x20    /* Block is suspected of containing errors */\r
+#define        BLK_RESTART     0x10    /* Block is Restart Marker */\r
+\r
+#define        BLK_BYTECOUNT   2       /* Bytes in this block */\r
+\r
+#endif /* !_FTP_H_ */\r
index c4db9efc86e8afd5d2fb3a399fbf42b48de59e6f..8f8a840f5be7d1cf4f947591392729188b2705b0 100644 (file)
@@ -126,6 +126,10 @@ struct _ns_flagdata {  int mask, shift;  };
 extern struct _ns_flagdata _ns_flagdata[];\r
 \r
 /* Accessor macros - this is part of the public interface. */\r
+#define ns_msg_getflag(handle, flag) ( \\r
+      ((handle)._flags & _ns_flagdata[flag].mask) \\r
+       >> _ns_flagdata[flag].shift \\r
+      )\r
 \r
 #define ns_msg_id(handle) ((handle)._id + 0)\r
 #define ns_msg_base(handle) ((handle)._msg + 0)\r
@@ -217,6 +221,28 @@ typedef enum __ns_update_operation {
   ns_uop_max = 2\r
 } ns_update_operation;\r
 \r
+/*\r
+ * This RR-like structure is particular to UPDATE.\r
+ */\r
+struct _ns_updrec {\r
+  struct _ns_updrec *r_prev; /* prev record */\r
+  struct _ns_updrec *r_next; /* next record */\r
+  u_int8_t  r_section;  /* ZONE/PREREQUISITE/UPDATE */\r
+  char *    r_dname;  /* owner of the RR */\r
+  u_int16_t r_class;  /* class number */\r
+  u_int16_t r_type;   /* type number */\r
+  u_int32_t r_ttl;    /* time to live */\r
+  u_char *  r_data;   /* rdata fields as text string */\r
+  u_int16_t r_size;   /* size of r_data field */\r
+  int   r_opcode; /* type of operation */\r
+  /* following fields for private use by the resolver/server routines */\r
+  struct _ns_updrec *r_grpnext;  /* next record when grouped */\r
+  struct databuf *r_dp;   /* databuf to process */\r
+  struct databuf *r_deldp;  /* databuf's deleted/overwritten */\r
+  u_int16_t r_zone;   /* zone number on server */\r
+};\r
+typedef struct _ns_updrec ns_updrec;\r
+\r
 /*%\r
  * This structure is used for TSIG authenticated messages\r
  */\r
@@ -456,25 +482,24 @@ typedef enum __ns_cert_types {
 #define NS_PUT16(s, cp) do { \\r
   uint32_t t_s = (uint32_t)(s); \\r
   u_char *t_cp = (u_char *)(cp); \\r
-  *t_cp++ = t_s >> 8; \\r
-  *t_cp   = t_s; \\r
+  *t_cp++ = (u_char)( t_s >> 8 ); \\r
+  *t_cp   = (u_char)( t_s ); \\r
   (cp) += NS_INT16SZ; \\r
 } while (/*CONSTCOND*/0)\r
 \r
 #define NS_PUT32(l, cp) do { \\r
   uint32_t t_l = (uint32_t)(l); \\r
   u_char *t_cp = (u_char *)(cp); \\r
-  *t_cp++ = t_l >> 24; \\r
-  *t_cp++ = t_l >> 16; \\r
-  *t_cp++ = t_l >> 8; \\r
-  *t_cp   = t_l; \\r
+  *t_cp++ = (u_char)( t_l >> 24 ); \\r
+  *t_cp++ = (u_char)( t_l >> 16 ); \\r
+  *t_cp++ = (u_char)( t_l >> 8 ); \\r
+  *t_cp   = (u_char)( t_l ); \\r
   (cp) += NS_INT32SZ; \\r
 } while (/*CONSTCOND*/0)\r
 \r
 /*%\r
  * ANSI C identifier hiding for bind's lib/nameser.\r
  */\r
-#define ns_msg_getflag    __ns_msg_getflag\r
 #define ns_get16    __ns_get16\r
 #define ns_get32    __ns_get32\r
 #define ns_put16    __ns_put16\r
@@ -511,7 +536,6 @@ typedef enum __ns_cert_types {
 #define ns_samename   __ns_samename\r
 \r
 __BEGIN_DECLS\r
-int   ns_msg_getflag(ns_msg, int);\r
 uint16_t  ns_get16(const u_char *);\r
 uint32_t  ns_get32(const u_char *);\r
 void    ns_put16(uint16_t, u_char *);\r
diff --git a/StdLib/Include/arpa/telnet.h b/StdLib/Include/arpa/telnet.h
new file mode 100644 (file)
index 0000000..d7c8ecb
--- /dev/null
@@ -0,0 +1,340 @@
+/*\r
+ * Copyright (c) 1983, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)telnet.h    8.2 (Berkeley) 12/15/93\r
+ */\r
+\r
+#ifndef _ARPA_TELNET_H_\r
+#define        _ARPA_TELNET_H_\r
+\r
+/*\r
+ * Definitions for the TELNET protocol.\r
+ */\r
+#define        IAC     255             /* interpret as command: */\r
+#define        DONT    254             /* you are not to use option */\r
+#define        DO      253             /* please, you use option */\r
+#define        WONT    252             /* I won't use option */\r
+#define        WILL    251             /* I will use option */\r
+#define        SB      250             /* interpret as subnegotiation */\r
+#define        GA      249             /* you may reverse the line */\r
+#define        EL      248             /* erase the current line */\r
+#define        EC      247             /* erase the current character */\r
+#define        AYT     246             /* are you there */\r
+#define        AO      245             /* abort output--but let prog finish */\r
+#define        IP      244             /* interrupt process--permanently */\r
+#define        BREAK   243             /* break */\r
+#define        DM      242             /* data mark--for connect. cleaning */\r
+#define        NOP     241             /* nop */\r
+#define        SE      240             /* end sub negotiation */\r
+#define EOR     239             /* end of record (transparent mode) */\r
+#define        ABORT   238             /* Abort process */\r
+#define        SUSP    237             /* Suspend process */\r
+#define        xEOF    236             /* End of file: EOF is already used... */\r
+\r
+#define SYNCH  242             /* for telfunc calls */\r
+\r
+#ifdef TELCMDS\r
+char *telcmds[] = {\r
+       "EOF", "SUSP", "ABORT", "EOR",\r
+       "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",\r
+       "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",\r
+       0\r
+};\r
+#else\r
+extern char *telcmds[];\r
+#endif\r
+\r
+#define        TELCMD_FIRST    xEOF\r
+#define        TELCMD_LAST     IAC\r
+#define        TELCMD_OK(x)    ((unsigned int)(x) <= TELCMD_LAST && \\r
+                        (unsigned int)(x) >= TELCMD_FIRST)\r
+#define        TELCMD(x)       telcmds[(x)-TELCMD_FIRST]\r
+\r
+/* telnet options */\r
+#define TELOPT_BINARY  0       /* 8-bit data path */\r
+#define TELOPT_ECHO    1       /* echo */\r
+#define        TELOPT_RCP      2       /* prepare to reconnect */\r
+#define        TELOPT_SGA      3       /* suppress go ahead */\r
+#define        TELOPT_NAMS     4       /* approximate message size */\r
+#define        TELOPT_STATUS   5       /* give status */\r
+#define        TELOPT_TM       6       /* timing mark */\r
+#define        TELOPT_RCTE     7       /* remote controlled transmission and echo */\r
+#define TELOPT_NAOL    8       /* negotiate about output line width */\r
+#define TELOPT_NAOP    9       /* negotiate about output page size */\r
+#define TELOPT_NAOCRD  10      /* negotiate about CR disposition */\r
+#define TELOPT_NAOHTS  11      /* negotiate about horizontal tabstops */\r
+#define TELOPT_NAOHTD  12      /* negotiate about horizontal tab disposition */\r
+#define TELOPT_NAOFFD  13      /* negotiate about formfeed disposition */\r
+#define TELOPT_NAOVTS  14      /* negotiate about vertical tab stops */\r
+#define TELOPT_NAOVTD  15      /* negotiate about vertical tab disposition */\r
+#define TELOPT_NAOLFD  16      /* negotiate about output LF disposition */\r
+#define TELOPT_XASCII  17      /* extended ascic character set */\r
+#define        TELOPT_LOGOUT   18      /* force logout */\r
+#define        TELOPT_BM       19      /* byte macro */\r
+#define        TELOPT_DET      20      /* data entry terminal */\r
+#define        TELOPT_SUPDUP   21      /* supdup protocol */\r
+#define        TELOPT_SUPDUPOUTPUT 22  /* supdup output */\r
+#define        TELOPT_SNDLOC   23      /* send location */\r
+#define        TELOPT_TTYPE    24      /* terminal type */\r
+#define        TELOPT_EOR      25      /* end or record */\r
+#define        TELOPT_TUID     26      /* TACACS user identification */\r
+#define        TELOPT_OUTMRK   27      /* output marking */\r
+#define        TELOPT_TTYLOC   28      /* terminal location number */\r
+#define        TELOPT_3270REGIME 29    /* 3270 regime */\r
+#define        TELOPT_X3PAD    30      /* X.3 PAD */\r
+#define        TELOPT_NAWS     31      /* window size */\r
+#define        TELOPT_TSPEED   32      /* terminal speed */\r
+#define        TELOPT_LFLOW    33      /* remote flow control */\r
+#define TELOPT_LINEMODE        34      /* Linemode option */\r
+#define TELOPT_XDISPLOC        35      /* X Display Location */\r
+#define TELOPT_OLD_ENVIRON 36  /* Old - Environment variables */\r
+#define        TELOPT_AUTHENTICATION 37/* Authenticate */\r
+#define        TELOPT_ENCRYPT  38      /* Encryption option */\r
+#define TELOPT_NEW_ENVIRON 39  /* New - Environment variables */\r
+#define        TELOPT_EXOPL    255     /* extended-options-list */\r
+\r
+\r
+#define        NTELOPTS        (1+TELOPT_NEW_ENVIRON)\r
+#ifdef TELOPTS\r
+char *telopts[NTELOPTS+1] = {\r
+       "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",\r
+       "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",\r
+       "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",\r
+       "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",\r
+       "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",\r
+       "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",\r
+       "TACACS UID", "OUTPUT MARKING", "TTYLOC",\r
+       "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",\r
+       "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",\r
+       "ENCRYPT", "NEW-ENVIRON",\r
+       0\r
+};\r
+#define        TELOPT_FIRST    TELOPT_BINARY\r
+#define        TELOPT_LAST     TELOPT_NEW_ENVIRON\r
+#define        TELOPT_OK(x)    ((unsigned int)(x) <= TELOPT_LAST)\r
+#define        TELOPT(x)       telopts[(x)-TELOPT_FIRST]\r
+#endif\r
+\r
+/* sub-option qualifiers */\r
+#define        TELQUAL_IS      0       /* option is... */\r
+#define        TELQUAL_SEND    1       /* send option */\r
+#define        TELQUAL_INFO    2       /* ENVIRON: informational version of IS */\r
+#define        TELQUAL_REPLY   2       /* AUTHENTICATION: client version of IS */\r
+#define        TELQUAL_NAME    3       /* AUTHENTICATION: client version of IS */\r
+\r
+#define        LFLOW_OFF               0       /* Disable remote flow control */\r
+#define        LFLOW_ON                1       /* Enable remote flow control */\r
+#define        LFLOW_RESTART_ANY       2       /* Restart output on any char */\r
+#define        LFLOW_RESTART_XON       3       /* Restart output only on XON */\r
+\r
+/*\r
+ * LINEMODE suboptions\r
+ */\r
+\r
+#define        LM_MODE         1\r
+#define        LM_FORWARDMASK  2\r
+#define        LM_SLC          3\r
+\r
+#define        MODE_EDIT       0x01\r
+#define        MODE_TRAPSIG    0x02\r
+#define        MODE_ACK        0x04\r
+#define MODE_SOFT_TAB  0x08\r
+#define MODE_LIT_ECHO  0x10\r
+\r
+#define        MODE_MASK       0x1f\r
+\r
+/* Not part of protocol, but needed to simplify things... */\r
+#define MODE_FLOW              0x0100\r
+#define MODE_ECHO              0x0200\r
+#define MODE_INBIN             0x0400\r
+#define MODE_OUTBIN            0x0800\r
+#define MODE_FORCE             0x1000\r
+\r
+#define        SLC_SYNCH       1\r
+#define        SLC_BRK         2\r
+#define        SLC_IP          3\r
+#define        SLC_AO          4\r
+#define        SLC_AYT         5\r
+#define        SLC_EOR         6\r
+#define        SLC_ABORT       7\r
+#define        SLC_EOF         8\r
+#define        SLC_SUSP        9\r
+#define        SLC_EC          10\r
+#define        SLC_EL          11\r
+#define        SLC_EW          12\r
+#define        SLC_RP          13\r
+#define        SLC_LNEXT       14\r
+#define        SLC_XON         15\r
+#define        SLC_XOFF        16\r
+#define        SLC_FORW1       17\r
+#define        SLC_FORW2       18\r
+#define SLC_MCL         19\r
+#define SLC_MCR         20\r
+#define SLC_MCWL        21\r
+#define SLC_MCWR        22\r
+#define SLC_MCBOL       23\r
+#define SLC_MCEOL       24\r
+#define SLC_INSRT       25\r
+#define SLC_OVER        26\r
+#define SLC_ECR         27\r
+#define SLC_EWR         28\r
+#define SLC_EBOL        29\r
+#define SLC_EEOL        30\r
+\r
+#define        NSLC            30\r
+\r
+/*\r
+ * For backwards compatability, we define SLC_NAMES to be the\r
+ * list of names if SLC_NAMES is not defined.\r
+ */\r
+#define        SLC_NAMELIST    "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR",  \\r
+                       "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \\r
+                       "LNEXT", "XON", "XOFF", "FORW1", "FORW2",       \\r
+                       "MCL", "MCR", "MCWL", "MCWR", "MCBOL",          \\r
+                       "MCEOL", "INSRT", "OVER", "ECR", "EWR",         \\r
+                       "EBOL", "EEOL",                                 \\r
+                       0\r
+\r
+#ifdef SLC_NAMES\r
+char *slc_names[] = {\r
+       SLC_NAMELIST\r
+};\r
+#else\r
+extern char *slc_names[];\r
+#define        SLC_NAMES SLC_NAMELIST\r
+#endif\r
+\r
+#define        SLC_NAME_OK(x)  ((unsigned int)(x) <= NSLC)\r
+#define SLC_NAME(x)    slc_names[x]\r
+\r
+#define        SLC_NOSUPPORT   0\r
+#define        SLC_CANTCHANGE  1\r
+#define        SLC_VARIABLE    2\r
+#define        SLC_DEFAULT     3\r
+#define        SLC_LEVELBITS   0x03\r
+\r
+#define        SLC_FUNC        0\r
+#define        SLC_FLAGS       1\r
+#define        SLC_VALUE       2\r
+\r
+#define        SLC_ACK         0x80\r
+#define        SLC_FLUSHIN     0x40\r
+#define        SLC_FLUSHOUT    0x20\r
+\r
+#define        OLD_ENV_VAR     1\r
+#define        OLD_ENV_VALUE   0\r
+#define        NEW_ENV_VAR     0\r
+#define        NEW_ENV_VALUE   1\r
+#define        ENV_ESC         2\r
+#define ENV_USERVAR    3\r
+\r
+/*\r
+ * AUTHENTICATION suboptions\r
+ */\r
+\r
+/*\r
+ * Who is authenticating who ...\r
+ */\r
+#define        AUTH_WHO_CLIENT         0       /* Client authenticating server */\r
+#define        AUTH_WHO_SERVER         1       /* Server authenticating client */\r
+#define        AUTH_WHO_MASK           1\r
+\r
+/*\r
+ * amount of authentication done\r
+ */\r
+#define        AUTH_HOW_ONE_WAY        0\r
+#define        AUTH_HOW_MUTUAL         2\r
+#define        AUTH_HOW_MASK           2\r
+\r
+#define        AUTHTYPE_NULL           0\r
+#define        AUTHTYPE_KERBEROS_V4    1\r
+#define        AUTHTYPE_KERBEROS_V5    2\r
+#define        AUTHTYPE_SPX            3\r
+#define        AUTHTYPE_MINK           4\r
+#define        AUTHTYPE_CNT            5\r
+\r
+#define        AUTHTYPE_TEST           99\r
+\r
+#ifdef AUTH_NAMES\r
+char *authtype_names[] = {\r
+       "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK",\r
+       0\r
+};\r
+#else\r
+extern char *authtype_names[];\r
+#endif\r
+\r
+#define        AUTHTYPE_NAME_OK(x)     ((unsigned int)(x) < AUTHTYPE_CNT)\r
+#define        AUTHTYPE_NAME(x)        authtype_names[x]\r
+\r
+/*\r
+ * ENCRYPTion suboptions\r
+ */\r
+#define        ENCRYPT_IS              0       /* I pick encryption type ... */\r
+#define        ENCRYPT_SUPPORT         1       /* I support encryption types ... */\r
+#define        ENCRYPT_REPLY           2       /* Initial setup response */\r
+#define        ENCRYPT_START           3       /* Am starting to send encrypted */\r
+#define        ENCRYPT_END             4       /* Am ending encrypted */\r
+#define        ENCRYPT_REQSTART        5       /* Request you start encrypting */\r
+#define        ENCRYPT_REQEND          6       /* Request you end encrypting */\r
+#define        ENCRYPT_ENC_KEYID       7\r
+#define        ENCRYPT_DEC_KEYID       8\r
+#define        ENCRYPT_CNT             9\r
+\r
+#define        ENCTYPE_ANY             0\r
+#define        ENCTYPE_DES_CFB64       1\r
+#define        ENCTYPE_DES_OFB64       2\r
+#define        ENCTYPE_CNT             3\r
+\r
+#ifdef ENCRYPT_NAMES\r
+char *encrypt_names[] = {\r
+       "IS", "SUPPORT", "REPLY", "START", "END",\r
+       "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",\r
+       0\r
+};\r
+char *enctype_names[] = {\r
+       "ANY", "DES_CFB64",  "DES_OFB64",\r
+       0\r
+};\r
+#else\r
+extern char *encrypt_names[];\r
+extern char *enctype_names[];\r
+#endif\r
+\r
+\r
+#define        ENCRYPT_NAME_OK(x)      ((unsigned int)(x) < ENCRYPT_CNT)\r
+#define        ENCRYPT_NAME(x)         encrypt_names[x]\r
+\r
+#define        ENCTYPE_NAME_OK(x)      ((unsigned int)(x) < ENCTYPE_CNT)\r
+#define        ENCTYPE_NAME(x)         enctype_names[x]\r
+\r
+#endif /* !_TELNET_H_ */\r
diff --git a/StdLib/Include/err.h b/StdLib/Include/err.h
new file mode 100644 (file)
index 0000000..6207d18
--- /dev/null
@@ -0,0 +1,25 @@
+/** @file error and warning output messages\r
+\r
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials                          \r
+  are licensed and made available under the terms and conditions of the BSD License         \r
+  which accompanies this distribution.  The full text of the license may be found at        \r
+  http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                            \r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+**/\r
+\r
+#ifndef _ERR_H_\r
+#define _ERR_H_\r
+\r
+//\r
+// Error and Warning outputs\r
+//\r
+\r
+void errx (int eval, const char *fmt, ...);\r
+void err  (int eval, const char *fmt, ...);\r
+void warnx(const char *fmt, ...);\r
+void warn (const char *fmt, ...);\r
+\r
+#endif
\ No newline at end of file
index f6d97bb9e5c7a3dd37ccc4955fd9925843a84056..9c6e071a2a5c0b5ed59414be6b36626841af2997 100644 (file)
@@ -34,6 +34,8 @@ extern  RETURN_STATUS   EFIerrno;
 \r
 // Define error number in terms of the ENUM in <sys/errno.h>\r
 \r
+#define ERESTART          -1                      /* restart syscall */\r
+\r
 #define EMINERRORVAL      __EMINERRORVAL          /* The lowest valid error value */\r
 \r
 #define EPERM             __EPERM                 /*  1   Operation not permitted */\r
diff --git a/StdLib/Include/glob.h b/StdLib/Include/glob.h
new file mode 100644 (file)
index 0000000..5842130
--- /dev/null
@@ -0,0 +1,109 @@
+/*     $NetBSD: glob.h,v 1.24 2008/09/13 17:05:07 christos Exp $       */\r
+\r
+/*\r
+ * Copyright (c) 1989, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to Berkeley by\r
+ * Guido van Rossum.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)glob.h      8.1 (Berkeley) 6/2/93\r
+ */\r
+\r
+#ifndef _GLOB_H_\r
+#define        _GLOB_H_\r
+\r
+#include <sys/cdefs.h>\r
+#include <sys/featuretest.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+\r
+#ifndef __gl_size_t\r
+#define __gl_size_t    size_t\r
+#endif\r
+#ifndef __gl_stat_t\r
+#define __gl_stat_t    struct stat\r
+#endif\r
+\r
+typedef struct {\r
+       __gl_size_t gl_pathc;   /* Count of total paths so far. */\r
+       __gl_size_t gl_matchc;  /* Count of paths matching pattern. */\r
+       __gl_size_t gl_offs;    /* Reserved at beginning of gl_pathv. */\r
+       int gl_flags;           /* Copy of flags parameter to glob. */\r
+       char **gl_pathv;        /* List of paths matching pattern. */\r
+                               /* Copy of errfunc parameter to glob. */\r
+       int (*gl_errfunc)(const char *, int);\r
+\r
+       /*\r
+        * Alternate filesystem access methods for glob; replacement\r
+        * versions of closedir(3), readdir(3), opendir(3), stat(2)\r
+        * and lstat(2).\r
+        */\r
+       void (*gl_closedir)(void *);\r
+       struct dirent *(*gl_readdir)(void *);   \r
+       void *(*gl_opendir)(const char *);\r
+       int (*gl_lstat)(const char *, __gl_stat_t *);\r
+       int (*gl_stat)(const char *, __gl_stat_t *);\r
+} glob_t;\r
+\r
+#define        GLOB_APPEND     0x0001  /* Append to output from previous call. */\r
+#define        GLOB_DOOFFS     0x0002  /* Use gl_offs. */\r
+#define        GLOB_ERR        0x0004  /* Return on error. */\r
+#define        GLOB_MARK       0x0008  /* Append / to matching directories. */\r
+#define        GLOB_NOCHECK    0x0010  /* Return pattern itself if nothing matches. */\r
+#define        GLOB_NOSORT     0x0020  /* Don't sort. */\r
+#define        GLOB_NOESCAPE   0x1000  /* Disable backslash escaping. */\r
+\r
+#define        GLOB_NOSPACE    (-1)    /* Malloc call failed. */\r
+#define        GLOB_ABORTED    (-2)    /* Unignored error. */\r
+#define        GLOB_NOMATCH    (-3)    /* No match, and GLOB_NOCHECK was not set. */\r
+#define        GLOB_NOSYS      (-4)    /* Implementation does not support function. */\r
+\r
+#if defined(_NETBSD_SOURCE) || defined(HAVE_NBTOOL_CONFIG_H)\r
+#define        GLOB_ALTDIRFUNC 0x0040  /* Use alternately specified directory funcs. */\r
+#define        GLOB_BRACE      0x0080  /* Expand braces ala csh. */\r
+#define        GLOB_MAGCHAR    0x0100  /* Pattern had globbing characters. */\r
+#define        GLOB_NOMAGIC    0x0200  /* GLOB_NOCHECK without magic chars (csh). */\r
+#define        GLOB_LIMIT      0x0400  /* Limit memory used by matches to ARG_MAX */\r
+#define        GLOB_TILDE      0x0800  /* Expand tilde names from the passwd file. */\r
+/*     GLOB_NOESCAPE   0x1000  above */\r
+#define        GLOB_PERIOD     0x2000  /* Allow metachars to match leading periods. */\r
+#define        GLOB_NO_DOTDIRS 0x4000  /* Make . and .. vanish from wildcards. */\r
+#define        GLOB_QUOTE      0       /* source compatibility */\r
+\r
+#define        GLOB_ABEND      GLOB_ABORTED    /* source compatibility */\r
+#endif\r
+\r
+__BEGIN_DECLS\r
+#ifndef __LIBC12_SOURCE__\r
+int    glob(const char * __restrict, int,\r
+    int (*)(const char *, int), glob_t * __restrict)    __RENAME(__glob30);\r
+void   globfree(glob_t *)                               __RENAME(__globfree30);\r
+#endif\r
+__END_DECLS\r
+\r
+#endif /* !_GLOB_H_ */\r
diff --git a/StdLib/Include/libgen.h b/StdLib/Include/libgen.h
new file mode 100644 (file)
index 0000000..3ee6738
--- /dev/null
@@ -0,0 +1,14 @@
+/** @file\r
+\r
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+char *dirname(char *path);\r
diff --git a/StdLib/Include/net/if.h b/StdLib/Include/net/if.h
new file mode 100644 (file)
index 0000000..0b8afa0
--- /dev/null
@@ -0,0 +1,227 @@
+/*\r
+ * Copyright (c) 1982, 1986, 1989, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)if.h        8.1 (Berkeley) 6/10/93\r
+ *     $Id: if.h,v 1.1.1.1 2006/05/30 06:12:41 hhzhou Exp $\r
+ */\r
+\r
+#ifndef _NET_IF_H_\r
+#define        _NET_IF_H_\r
+\r
+/*\r
+ * <net/if.h> does not depend on <sys/time.h> on most other systems.  This\r
+ * helps userland compatability.  (struct timeval ifi_lastchange)\r
+ */\r
+#ifndef KERNEL\r
+#include <sys/time.h>\r
+#endif\r
+\r
+/*\r
+ * Structure describing information about an interface\r
+ * which may be of interest to management entities.\r
+ */\r
+struct if_data {\r
+       /* generic interface information */\r
+       u_char  ifi_type;               /* ethernet, tokenring, etc */\r
+       u_char  ifi_physical;           /* e.g., AUI, Thinnet, 10base-T, etc */\r
+       u_char  ifi_addrlen;            /* media address length */\r
+       u_char  ifi_hdrlen;             /* media header length */\r
+       u_char  ifi_recvquota;          /* polling quota for receive intrs */\r
+       u_char  ifi_xmitquota;          /* polling quota for xmit intrs */\r
+       u_long  ifi_mtu;                /* maximum transmission unit */\r
+       u_long  ifi_metric;             /* routing metric (external only) */\r
+       u_long  ifi_baudrate;           /* linespeed */\r
+       /* volatile statistics */\r
+       u_long  ifi_ipackets;           /* packets received on interface */\r
+       u_long  ifi_ierrors;            /* input errors on interface */\r
+       u_long  ifi_opackets;           /* packets sent on interface */\r
+       u_long  ifi_oerrors;            /* output errors on interface */\r
+       u_long  ifi_collisions;         /* collisions on csma interfaces */\r
+       u_long  ifi_ibytes;             /* total number of octets received */\r
+       u_long  ifi_obytes;             /* total number of octets sent */\r
+       u_long  ifi_imcasts;            /* packets received via multicast */\r
+       u_long  ifi_omcasts;            /* packets sent via multicast */\r
+       u_long  ifi_iqdrops;            /* dropped on input, this interface */\r
+       u_long  ifi_noproto;            /* destined for unsupported protocol */\r
+       u_long  ifi_recvtiming;         /* usec spent receiving when timing */\r
+       u_long  ifi_xmittiming;         /* usec spent xmitting when timing */\r
+       struct  timeval ifi_lastchange; /* time of last administrative change */\r
+};\r
+\r
+#define        IFF_UP          0x1             /* interface is up */\r
+#define        IFF_BROADCAST   0x2             /* broadcast address valid */\r
+#define        IFF_DEBUG       0x4             /* turn on debugging */\r
+#define        IFF_LOOPBACK    0x8             /* is a loopback net */\r
+#define        IFF_POINTOPOINT 0x10            /* interface is point-to-point link */\r
+/*#define IFF_NOTRAILERS 0x20           * obsolete: avoid use of trailers */\r
+#define        IFF_RUNNING     0x40            /* resources allocated */\r
+#define        IFF_NOARP       0x80            /* no address resolution protocol */\r
+#define        IFF_PROMISC     0x100           /* receive all packets */\r
+#define        IFF_ALLMULTI    0x200           /* receive all multicast packets */\r
+#define        IFF_OACTIVE     0x400           /* transmission in progress */\r
+#define        IFF_SIMPLEX     0x800           /* can't hear own transmissions */\r
+#define        IFF_LINK0       0x1000          /* per link layer defined bit */\r
+#define        IFF_LINK1       0x2000          /* per link layer defined bit */\r
+#define        IFF_LINK2       0x4000          /* per link layer defined bit */\r
+#define        IFF_ALTPHYS     IFF_LINK2       /* use alternate physical connection */\r
+#define        IFF_MULTICAST   0x8000          /* supports multicast */\r
+\r
+/* flags set internally only: */\r
+#define        IFF_CANTCHANGE \\r
+       (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\\r
+           IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)\r
+\r
+#define        IFQ_MAXLEN      50\r
+#define        IFNET_SLOWHZ    1               /* granularity is 1 second */\r
+\r
+/*\r
+ * Message format for use in obtaining information about interfaces\r
+ * from getkerninfo and the routing socket\r
+ */\r
+struct if_msghdr {\r
+       u_short ifm_msglen;     /* to skip over non-understood messages */\r
+       u_char  ifm_version;    /* future binary compatability */\r
+       u_char  ifm_type;       /* message type */\r
+       int     ifm_addrs;      /* like rtm_addrs */\r
+       int     ifm_flags;      /* value of if_flags */\r
+       u_short ifm_index;      /* index for associated ifp */\r
+       struct  if_data ifm_data;/* statistics and other data about if */\r
+};\r
+\r
+/*\r
+ * Message format for use in obtaining information about interface addresses\r
+ * from getkerninfo and the routing socket\r
+ */\r
+struct ifa_msghdr {\r
+       u_short ifam_msglen;    /* to skip over non-understood messages */\r
+       u_char  ifam_version;   /* future binary compatability */\r
+       u_char  ifam_type;      /* message type */\r
+       int     ifam_addrs;     /* like rtm_addrs */\r
+       int     ifam_flags;     /* value of ifa_flags */\r
+       u_short ifam_index;     /* index for associated ifp */\r
+       int     ifam_metric;    /* value of ifa_metric */\r
+};\r
+\r
+/*\r
+ * Message format for use in obtaining information about multicast addresses\r
+ * from the routing socket\r
+ */\r
+struct ifma_msghdr {\r
+       u_short ifmam_msglen;   /* to skip over non-understood messages */\r
+       u_char  ifmam_version;  /* future binary compatability */\r
+       u_char  ifmam_type;     /* message type */\r
+       int     ifmam_addrs;    /* like rtm_addrs */\r
+       int     ifmam_flags;    /* value of ifa_flags */\r
+       u_short ifmam_index;    /* index for associated ifp */\r
+};\r
+\r
+/*\r
+ * Interface request structure used for socket\r
+ * ioctl's.  All interface ioctl's must have parameter\r
+ * definitions which begin with ifr_name.  The\r
+ * remainder may be interface specific.\r
+ */\r
+struct ifreq {\r
+#define        IFNAMSIZ        16\r
+       char    ifr_name[IFNAMSIZ];             /* if name, e.g. "en0" */\r
+       union {\r
+               struct  sockaddr ifru_addr;\r
+               struct  sockaddr ifru_dstaddr;\r
+               struct  sockaddr ifru_broadaddr;\r
+               short   ifru_flags;\r
+               int     ifru_metric;\r
+               int     ifru_mtu;\r
+               int     ifru_phys;\r
+               int     ifru_media;\r
+               caddr_t ifru_data;\r
+       } ifr_ifru;\r
+#define        ifr_addr        ifr_ifru.ifru_addr      /* address */\r
+#define        ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-to-p link */\r
+#define        ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address */\r
+#define        ifr_flags       ifr_ifru.ifru_flags     /* flags */\r
+#define        ifr_metric      ifr_ifru.ifru_metric    /* metric */\r
+#define        ifr_mtu         ifr_ifru.ifru_mtu       /* mtu */\r
+#define ifr_phys       ifr_ifru.ifru_phys      /* physical wire */\r
+#define ifr_media      ifr_ifru.ifru_media     /* physical media */\r
+#define        ifr_data        ifr_ifru.ifru_data      /* for use by interface */\r
+};\r
+\r
+#define        _SIZEOF_ADDR_IFREQ(ifr) \\r
+       ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \\r
+        (sizeof(struct ifreq) - sizeof(struct sockaddr) + \\r
+         (ifr).ifr_addr.sa_len) : sizeof(struct ifreq))\r
+\r
+struct ifaliasreq {\r
+       char    ifra_name[IFNAMSIZ];            /* if name, e.g. "en0" */\r
+       struct  sockaddr ifra_addr;\r
+       struct  sockaddr ifra_broadaddr;\r
+       struct  sockaddr ifra_mask;\r
+};\r
+\r
+struct ifmediareq {\r
+       char    ifm_name[IFNAMSIZ];     /* if name, e.g. "en0" */\r
+       int     ifm_current;            /* current media options */\r
+       int     ifm_mask;               /* don't care mask */\r
+       int     ifm_status;             /* media status */\r
+       int     ifm_active;             /* active options */\r
+       int     ifm_count;              /* # entries in ifm_ulist array */\r
+       int     *ifm_ulist;             /* media words */\r
+};\r
+/*\r
+ * Structure used in SIOCGIFCONF request.\r
+ * Used to retrieve interface configuration\r
+ * for machine (useful for programs which\r
+ * must know all networks accessible).\r
+ */\r
+struct ifconf {\r
+       int     ifc_len;                /* size of associated buffer */\r
+       union {\r
+               caddr_t ifcu_buf;\r
+               struct  ifreq *ifcu_req;\r
+       } ifc_ifcu;\r
+#define        ifc_buf ifc_ifcu.ifcu_buf       /* buffer address */\r
+#define        ifc_req ifc_ifcu.ifcu_req       /* array of structures returned */\r
+};\r
+\r
+#ifdef KERNEL\r
+#ifdef MALLOC_DECLARE\r
+MALLOC_DECLARE(M_IFADDR);\r
+MALLOC_DECLARE(M_IFMADDR);\r
+#endif\r
+#endif\r
+\r
+/* XXX - this should go away soon */\r
+#ifdef KERNEL\r
+#include <net/if_var.h>\r
+#endif\r
+\r
+#endif /* !_NET_IF_H_ */\r
diff --git a/StdLib/Include/net/if_dl.h b/StdLib/Include/net/if_dl.h
new file mode 100644 (file)
index 0000000..3935551
--- /dev/null
@@ -0,0 +1,86 @@
+/*\r
+ * Copyright (c) 1990, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)if_dl.h     8.1 (Berkeley) 6/10/93\r
+ * $Id: if_dl.h,v 1.1.1.1 2006/05/30 06:12:42 hhzhou Exp $\r
+ */\r
+\r
+#ifndef _NET_IF_DL_H_\r
+#define _NET_IF_DL_H_\r
+\r
+/*\r
+ * A Link-Level Sockaddr may specify the interface in one of two\r
+ * ways: either by means of a system-provided index number (computed\r
+ * anew and possibly differently on every reboot), or by a human-readable\r
+ * string such as "il0" (for managerial convenience).\r
+ *\r
+ * Census taking actions, such as something akin to SIOCGCONF would return\r
+ * both the index and the human name.\r
+ *\r
+ * High volume transactions (such as giving a link-level ``from'' address\r
+ * in a recvfrom or recvmsg call) may be likely only to provide the indexed\r
+ * form, (which requires fewer copy operations and less space).\r
+ *\r
+ * The form and interpretation  of the link-level address is purely a matter\r
+ * of convention between the device driver and its consumers; however, it is\r
+ * expected that all drivers for an interface of a given if_type will agree.\r
+ */\r
+\r
+/*\r
+ * Structure of a Link-Level sockaddr:\r
+ */\r
+struct sockaddr_dl {\r
+       u_char  sdl_len;        /* Total length of sockaddr */\r
+       u_char  sdl_family;     /* AF_DLI */\r
+       u_short sdl_index;      /* if != 0, system given index for interface */\r
+       u_char  sdl_type;       /* interface type */\r
+       u_char  sdl_nlen;       /* interface name length, no trailing 0 reqd. */\r
+       u_char  sdl_alen;       /* link level address length */\r
+       u_char  sdl_slen;       /* link layer selector length */\r
+       char    sdl_data[12];   /* minimum work area, can be larger;\r
+                                  contains both if name and ll address */\r
+};\r
+\r
+#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))\r
+\r
+#ifndef KERNEL\r
+\r
+#include <sys/EfiCdefs.h>\r
+\r
+__BEGIN_DECLS\r
+void   link_addr __P((const char *, struct sockaddr_dl *));\r
+char   *link_ntoa __P((const struct sockaddr_dl *));\r
+__END_DECLS\r
+\r
+#endif /* !KERNEL */\r
+\r
+#endif\r
diff --git a/StdLib/Include/net/radix.h b/StdLib/Include/net/radix.h
new file mode 100644 (file)
index 0000000..20ad34b
--- /dev/null
@@ -0,0 +1,170 @@
+/*\r
+ * Copyright (c) 1988, 1989, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)radix.h     8.2 (Berkeley) 10/31/94\r
+ *     $Id: radix.h,v 1.1.1.1 2006/05/30 06:12:46 hhzhou Exp $\r
+ */\r
+\r
+#ifndef _RADIX_H_\r
+#define        _RADIX_H_\r
+\r
+#ifdef MALLOC_DECLARE\r
+MALLOC_DECLARE(M_RTABLE);\r
+#endif\r
+\r
+/*\r
+ * Radix search tree node layout.\r
+ */\r
+\r
+struct radix_node {\r
+       struct  radix_mask *rn_mklist;  /* list of masks contained in subtree */\r
+       struct  radix_node *rn_p;       /* parent */\r
+       short   rn_b;                   /* bit offset; -1-index(netmask) */\r
+       char    rn_bmask;               /* node: mask for bit test*/\r
+       u_char  rn_flags;               /* enumerated next */\r
+#define RNF_NORMAL     1               /* leaf contains normal route */\r
+#define RNF_ROOT       2               /* leaf is root leaf for tree */\r
+#define RNF_ACTIVE     4               /* This node is alive (for rtfree) */\r
+       union {\r
+               struct {                        /* leaf only data: */\r
+                       caddr_t rn_Key;         /* object of search */\r
+                       caddr_t rn_Mask;        /* netmask, if present */\r
+                       struct  radix_node *rn_Dupedkey;\r
+               } rn_leaf;\r
+               struct {                        /* node only data: */\r
+                       int     rn_Off;         /* where to start compare */\r
+                       struct  radix_node *rn_L;/* progeny */\r
+                       struct  radix_node *rn_R;/* progeny */\r
+               } rn_node;\r
+       }               rn_u;\r
+#ifdef RN_DEBUG\r
+       int rn_info;\r
+       struct radix_node *rn_twin;\r
+       struct radix_node *rn_ybro;\r
+#endif\r
+};\r
+\r
+#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey\r
+#define rn_key rn_u.rn_leaf.rn_Key\r
+#define rn_mask rn_u.rn_leaf.rn_Mask\r
+#define rn_off rn_u.rn_node.rn_Off\r
+#define rn_l rn_u.rn_node.rn_L\r
+#define rn_r rn_u.rn_node.rn_R\r
+\r
+/*\r
+ * Annotations to tree concerning potential routes applying to subtrees.\r
+ */\r
+\r
+struct radix_mask {\r
+       short   rm_b;                   /* bit offset; -1-index(netmask) */\r
+       char    rm_unused;              /* cf. rn_bmask */\r
+       u_char  rm_flags;               /* cf. rn_flags */\r
+       struct  radix_mask *rm_mklist;  /* more masks to try */\r
+       union   {\r
+               caddr_t rmu_mask;               /* the mask */\r
+               struct  radix_node *rmu_leaf;   /* for normal routes */\r
+       }       rm_rmu;\r
+       int     rm_refs;                /* # of references to this struct */\r
+};\r
+\r
+#define rm_mask rm_rmu.rmu_mask\r
+#define rm_leaf rm_rmu.rmu_leaf                /* extra field would make 32 bytes */\r
+\r
+#define MKGet(m) {\\r
+       if (rn_mkfreelist) {\\r
+               m = rn_mkfreelist; \\r
+               rn_mkfreelist = (m)->rm_mklist; \\r
+       } else \\r
+               R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\\r
+\r
+#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);}\r
+\r
+typedef int walktree_f_t __P((struct radix_node *, void *));\r
+\r
+struct radix_node_head {\r
+       struct  radix_node *rnh_treetop;\r
+       int     rnh_addrsize;           /* permit, but not require fixed keys */\r
+       int     rnh_pktsize;            /* permit, but not require fixed keys */\r
+       struct  radix_node *(*rnh_addaddr)      /* add based on sockaddr */\r
+               __P((void *v, void *mask,\r
+                    struct radix_node_head *head, struct radix_node nodes[]));\r
+       struct  radix_node *(*rnh_addpkt)       /* add based on packet hdr */\r
+               __P((void *v, void *mask,\r
+                    struct radix_node_head *head, struct radix_node nodes[]));\r
+       struct  radix_node *(*rnh_deladdr)      /* remove based on sockaddr */\r
+               __P((void *v, void *mask, struct radix_node_head *head));\r
+       struct  radix_node *(*rnh_delpkt)       /* remove based on packet hdr */\r
+               __P((void *v, void *mask, struct radix_node_head *head));\r
+       struct  radix_node *(*rnh_matchaddr)    /* locate based on sockaddr */\r
+               __P((void *v, struct radix_node_head *head));\r
+       struct  radix_node *(*rnh_lookup)       /* locate based on sockaddr */\r
+               __P((void *v, void *mask, struct radix_node_head *head));\r
+       struct  radix_node *(*rnh_matchpkt)     /* locate based on packet hdr */\r
+               __P((void *v, struct radix_node_head *head));\r
+       int     (*rnh_walktree)                 /* traverse tree */\r
+               __P((struct radix_node_head *head, walktree_f_t *f, void *w));\r
+       int     (*rnh_walktree_from)            /* traverse tree below a */\r
+               __P((struct radix_node_head *head, void *a, void *m,\r
+                    walktree_f_t *f, void *w));\r
+       void    (*rnh_close)    /* do something when the last ref drops */\r
+               __P((struct radix_node *rn, struct radix_node_head *head));\r
+       struct  radix_node rnh_nodes[3];        /* empty tree for common case */\r
+};\r
+\r
+#ifndef KERNEL\r
+#define Bcmp(a, b, n) bcmp(((char *)(a)), ((char *)(b)), (n))\r
+#define Bcopy(a, b, n) bcopy(((char *)(a)), ((char *)(b)), (unsigned)(n))\r
+#define Bzero(p, n) bzero((char *)(p), (int)(n));\r
+#define R_Malloc(p, t, n) (p = (t) malloc((unsigned int)(n)))\r
+#define Free(p) free((char *)p);\r
+#else\r
+#define Bcmp(a, b, n) bcmp(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))\r
+#define Bcopy(a, b, n) bcopy(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))\r
+#define Bzero(p, n) bzero((caddr_t)(p), (unsigned)(n));\r
+#define R_Malloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_DONTWAIT))\r
+#define Free(p) free((caddr_t)p, M_RTABLE);\r
+#endif /*KERNEL*/\r
+\r
+void    rn_init __P((void));\r
+int     rn_inithead __P((void **, int));\r
+int     rn_refines __P((void *, void *));\r
+struct radix_node\r
+        *rn_addmask __P((void *, int, int)),\r
+        *rn_addroute __P((void *, void *, struct radix_node_head *,\r
+                       struct radix_node [2])),\r
+        *rn_delete __P((void *, void *, struct radix_node_head *)),\r
+        *rn_lookup __P((void *v_arg, void *m_arg,\r
+                       struct radix_node_head *head)),\r
+        *rn_match __P((void *, struct radix_node_head *));\r
+\r
+\r
+#endif /* _RADIX_H_ */\r
diff --git a/StdLib/Include/net/route.h b/StdLib/Include/net/route.h
new file mode 100644 (file)
index 0000000..ec5d9eb
--- /dev/null
@@ -0,0 +1,292 @@
+/*\r
+ * Copyright (c) 1980, 1986, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)route.h     8.3 (Berkeley) 4/19/94\r
+ * $Id: route.h,v 1.1.1.1 2006/05/30 06:12:46 hhzhou Exp $\r
+ */\r
+\r
+#ifndef _NET_ROUTE_H_\r
+#define _NET_ROUTE_H_\r
+\r
+#define        __P(protos)     protos          /* full-blown ANSI C */\r
+\r
+\r
+/*\r
+ * Kernel resident routing tables.\r
+ *\r
+ * The routing tables are initialized when interface addresses\r
+ * are set by making entries for all directly connected interfaces.\r
+ */\r
+\r
+/*\r
+ * A route consists of a destination address and a reference\r
+ * to a routing entry.  These are often held by protocols\r
+ * in their control blocks, e.g. inpcb.\r
+ */\r
+struct route {\r
+       struct  rtentry *ro_rt;\r
+       struct  sockaddr ro_dst;\r
+};\r
+\r
+/*\r
+ * These numbers are used by reliable protocols for determining\r
+ * retransmission behavior and are included in the routing structure.\r
+ */\r
+struct rt_metrics {\r
+       u_long  rmx_locks;      /* Kernel must leave these values alone */\r
+       u_long  rmx_mtu;        /* MTU for this path */\r
+       u_long  rmx_hopcount;   /* max hops expected */\r
+       u_long  rmx_expire;     /* lifetime for route, e.g. redirect */\r
+       u_long  rmx_recvpipe;   /* inbound delay-bandwidth product */\r
+       u_long  rmx_sendpipe;   /* outbound delay-bandwidth product */\r
+       u_long  rmx_ssthresh;   /* outbound gateway buffer limit */\r
+       u_long  rmx_rtt;        /* estimated round trip time */\r
+       u_long  rmx_rttvar;     /* estimated rtt variance */\r
+       u_long  rmx_pksent;     /* packets sent using this route */\r
+       u_long  rmx_filler[4];  /* will be used for T/TCP later */\r
+};\r
+\r
+/*\r
+ * rmx_rtt and rmx_rttvar are stored as microseconds;\r
+ * RTTTOPRHZ(rtt) converts to a value suitable for use\r
+ * by a protocol slowtimo counter.\r
+ */\r
+#define        RTM_RTTUNIT     1000000 /* units for rtt, rttvar, as units per sec */\r
+#define        RTTTOPRHZ(r)    ((r) / (RTM_RTTUNIT / PR_SLOWHZ))\r
+\r
+/*\r
+ * XXX kernel function pointer `rt_output' is visible to applications.\r
+ */\r
+struct mbuf;\r
+\r
+/*\r
+ * We distinguish between routes to hosts and routes to networks,\r
+ * preferring the former if available.  For each route we infer\r
+ * the interface to use from the gateway address supplied when\r
+ * the route was entered.  Routes that forward packets through\r
+ * gateways are marked so that the output routines know to address the\r
+ * gateway rather than the ultimate destination.\r
+ */\r
+#ifndef RNF_NORMAL\r
+#include <net/radix.h>\r
+#endif\r
+struct rtentry {\r
+       struct  radix_node rt_nodes[2]; /* tree glue, and other values */\r
+#define        rt_key(r)       ((struct sockaddr *)((r)->rt_nodes->rn_key))\r
+#define        rt_mask(r)      ((struct sockaddr *)((r)->rt_nodes->rn_mask))\r
+       struct  sockaddr *rt_gateway;   /* value */\r
+       short   rt_filler;              /* was short flags field */\r
+       short   rt_refcnt;              /* # held references */\r
+       u_long  rt_flags;               /* up/down?, host/net */\r
+       struct  ifnet *rt_ifp;          /* the answer: interface to use */\r
+       struct  ifaddr *rt_ifa;         /* the answer: interface to use */\r
+       struct  sockaddr *rt_genmask;   /* for generation of cloned routes */\r
+       caddr_t rt_llinfo;              /* pointer to link level info cache */\r
+       struct  rt_metrics rt_rmx;      /* metrics used by rx'ing protocols */\r
+       struct  rtentry *rt_gwroute;    /* implied entry for gatewayed routes */\r
+       int     (*rt_output) __P((struct ifnet *, struct mbuf *,\r
+                                 struct sockaddr *, struct rtentry *));\r
+                                       /* output routine for this (rt,if) */\r
+       struct  rtentry *rt_parent;     /* cloning parent of this route */\r
+       void    *rt_filler2;            /* more filler */\r
+};\r
+\r
+/*\r
+ * Following structure necessary for 4.3 compatibility;\r
+ * We should eventually move it to a compat file.\r
+ */\r
+struct ortentry {\r
+       u_long  rt_hash;                /* to speed lookups */\r
+       struct  sockaddr rt_dst;        /* key */\r
+       struct  sockaddr rt_gateway;    /* value */\r
+       short   rt_flags;               /* up/down?, host/net */\r
+       short   rt_refcnt;              /* # held references */\r
+       u_long  rt_use;                 /* raw # packets forwarded */\r
+       struct  ifnet *rt_ifp;          /* the answer: interface to use */\r
+};\r
+\r
+#define rt_use rt_rmx.rmx_pksent\r
+\r
+#define        RTF_UP          0x1             /* route usable */\r
+#define        RTF_GATEWAY     0x2             /* destination is a gateway */\r
+#define        RTF_HOST        0x4             /* host entry (net otherwise) */\r
+#define        RTF_REJECT      0x8             /* host or net unreachable */\r
+#define        RTF_DYNAMIC     0x10            /* created dynamically (by redirect) */\r
+#define        RTF_MODIFIED    0x20            /* modified dynamically (by redirect) */\r
+#define RTF_DONE       0x40            /* message confirmed */\r
+/*                     0x80               unused */\r
+#define RTF_CLONING    0x100           /* generate new routes on use */\r
+#define RTF_XRESOLVE   0x200           /* external daemon resolves name */\r
+#define RTF_LLINFO     0x400           /* generated by link layer (e.g. ARP) */\r
+#define RTF_STATIC     0x800           /* manually added */\r
+#define RTF_BLACKHOLE  0x1000          /* just discard pkts (during updates) */\r
+#define RTF_PROTO2     0x4000          /* protocol specific routing flag */\r
+#define RTF_PROTO1     0x8000          /* protocol specific routing flag */\r
+\r
+#define RTF_PRCLONING  0x10000         /* protocol requires cloning */\r
+#define RTF_WASCLONED  0x20000         /* route generated through cloning */\r
+#define RTF_PROTO3     0x40000         /* protocol specific routing flag */\r
+/*                     0x80000            unused */\r
+#define RTF_PINNED     0x100000        /* future use */\r
+#define        RTF_LOCAL       0x200000        /* route represents a local address */\r
+#define        RTF_BROADCAST   0x400000        /* route represents a bcast address */\r
+#define        RTF_MULTICAST   0x800000        /* route represents a mcast address */\r
+                                       /* 0x1000000 and up unassigned */\r
+\r
+/*\r
+ * Routing statistics.\r
+ */\r
+struct rtstat {\r
+       short   rts_badredirect;        /* bogus redirect calls */\r
+       short   rts_dynamic;            /* routes created by redirects */\r
+       short   rts_newgateway;         /* routes modified by redirects */\r
+       short   rts_unreach;            /* lookups which failed */\r
+       short   rts_wildcard;           /* lookups satisfied by a wildcard */\r
+};\r
+/*\r
+ * Structures for routing messages.\r
+ */\r
+struct rt_msghdr {\r
+       u_short rtm_msglen;     /* to skip over non-understood messages */\r
+       u_char  rtm_version;    /* future binary compatibility */\r
+       u_char  rtm_type;       /* message type */\r
+       u_short rtm_index;      /* index for associated ifp */\r
+       int     rtm_flags;      /* flags, incl. kern & message, e.g. DONE */\r
+       int     rtm_addrs;      /* bitmask identifying sockaddrs in msg */\r
+       pid_t   rtm_pid;        /* identify sender */\r
+       int     rtm_seq;        /* for sender to identify action */\r
+       int     rtm_errno;      /* why failed */\r
+       int     rtm_use;        /* from rtentry */\r
+       u_long  rtm_inits;      /* which metrics we are initializing */\r
+       struct  rt_metrics rtm_rmx; /* metrics themselves */\r
+};\r
+\r
+#define RTM_VERSION    5       /* Up the ante and ignore older versions */\r
+\r
+#define RTM_ADD                0x1     /* Add Route */\r
+#define RTM_DELETE     0x2     /* Delete Route */\r
+#define RTM_CHANGE     0x3     /* Change Metrics or flags */\r
+#define RTM_GET                0x4     /* Report Metrics */\r
+#define RTM_LOSING     0x5     /* Kernel Suspects Partitioning */\r
+#define RTM_REDIRECT   0x6     /* Told to use different route */\r
+#define RTM_MISS       0x7     /* Lookup failed on this address */\r
+#define RTM_LOCK       0x8     /* fix specified metrics */\r
+#define RTM_OLDADD     0x9     /* caused by SIOCADDRT */\r
+#define RTM_OLDDEL     0xa     /* caused by SIOCDELRT */\r
+#define RTM_RESOLVE    0xb     /* req to resolve dst to LL addr */\r
+#define RTM_NEWADDR    0xc     /* address being added to iface */\r
+#define RTM_DELADDR    0xd     /* address being removed from iface */\r
+#define RTM_IFINFO     0xe     /* iface going up/down etc. */\r
+#define        RTM_NEWMADDR    0xf     /* mcast group membership being added to if */\r
+#define        RTM_DELMADDR    0x10    /* mcast group membership being deleted */\r
+\r
+#define RTV_MTU                0x1     /* init or lock _mtu */\r
+#define RTV_HOPCOUNT   0x2     /* init or lock _hopcount */\r
+#define RTV_EXPIRE     0x4     /* init or lock _hopcount */\r
+#define RTV_RPIPE      0x8     /* init or lock _recvpipe */\r
+#define RTV_SPIPE      0x10    /* init or lock _sendpipe */\r
+#define RTV_SSTHRESH   0x20    /* init or lock _ssthresh */\r
+#define RTV_RTT                0x40    /* init or lock _rtt */\r
+#define RTV_RTTVAR     0x80    /* init or lock _rttvar */\r
+\r
+/*\r
+ * Bitmask values for rtm_addr.\r
+ */\r
+#define RTA_DST                0x1     /* destination sockaddr present */\r
+#define RTA_GATEWAY    0x2     /* gateway sockaddr present */\r
+#define RTA_NETMASK    0x4     /* netmask sockaddr present */\r
+#define RTA_GENMASK    0x8     /* cloning mask sockaddr present */\r
+#define RTA_IFP                0x10    /* interface name sockaddr present */\r
+#define RTA_IFA                0x20    /* interface addr sockaddr present */\r
+#define RTA_AUTHOR     0x40    /* sockaddr for author of redirect */\r
+#define RTA_BRD                0x80    /* for NEWADDR, broadcast or p-p dest addr */\r
+\r
+/*\r
+ * Index offsets for sockaddr array for alternate internal encoding.\r
+ */\r
+#define RTAX_DST       0       /* destination sockaddr present */\r
+#define RTAX_GATEWAY   1       /* gateway sockaddr present */\r
+#define RTAX_NETMASK   2       /* netmask sockaddr present */\r
+#define RTAX_GENMASK   3       /* cloning mask sockaddr present */\r
+#define RTAX_IFP       4       /* interface name sockaddr present */\r
+#define RTAX_IFA       5       /* interface addr sockaddr present */\r
+#define RTAX_AUTHOR    6       /* sockaddr for author of redirect */\r
+#define RTAX_BRD       7       /* for NEWADDR, broadcast or p-p dest addr */\r
+#define RTAX_MAX       8       /* size of array to allocate */\r
+\r
+struct rt_addrinfo {\r
+       int     rti_addrs;\r
+       struct  sockaddr *rti_info[RTAX_MAX];\r
+};\r
+\r
+struct route_cb {\r
+       int     ip_count;\r
+       int     ipx_count;\r
+       int     ns_count;\r
+       int     iso_count;\r
+       int     any_count;\r
+};\r
+\r
+#ifdef KERNEL\r
+#define        RTFREE(rt) \\r
+       if ((rt)->rt_refcnt <= 1) \\r
+               rtfree(rt); \\r
+       else \\r
+               (rt)->rt_refcnt--;\r
+\r
+extern struct route_cb route_cb;\r
+extern struct radix_node_head *rt_tables[AF_MAX+1];\r
+\r
+struct ifmultiaddr;\r
+struct proc;\r
+\r
+void    route_init __P((void));\r
+void    rt_ifmsg __P((struct ifnet *));\r
+void    rt_missmsg __P((int, struct rt_addrinfo *, int, int));\r
+void    rt_newaddrmsg __P((int, struct ifaddr *, int, struct rtentry *));\r
+void    rt_newmaddrmsg __P((int, struct ifmultiaddr *));\r
+int     rt_setgate __P((struct rtentry *,\r
+           struct sockaddr *, struct sockaddr *));\r
+void    rtalloc __P((struct route *));\r
+void    rtalloc_ign __P((struct route *, unsigned long));\r
+struct rtentry *\r
+        rtalloc1 __P((struct sockaddr *, int, unsigned long));\r
+void    rtfree __P((struct rtentry *));\r
+int     rtinit __P((struct ifaddr *, int, int));\r
+int     rtioctl __P((int, caddr_t, struct proc *));\r
+void    rtredirect __P((struct sockaddr *, struct sockaddr *,\r
+           struct sockaddr *, int, struct sockaddr *, struct rtentry **));\r
+int     rtrequest __P((int, struct sockaddr *,\r
+           struct sockaddr *, struct sockaddr *, int, struct rtentry **));\r
+#endif\r
+\r
+#endif\r
diff --git a/StdLib/Include/netatalk/at.h b/StdLib/Include/netatalk/at.h
new file mode 100644 (file)
index 0000000..6c2b4f4
--- /dev/null
@@ -0,0 +1,92 @@
+/*\r
+ * Copyright (c) 1990,1991 Regents of The University of Michigan.\r
+ * All Rights Reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and\r
+ * its documentation for any purpose and without fee is hereby granted,\r
+ * provided that the above copyright notice appears in all copies and\r
+ * that both that copyright notice and this permission notice appear\r
+ * in supporting documentation, and that the name of The University\r
+ * of Michigan not be used in advertising or publicity pertaining to\r
+ * distribution of the software without specific, written prior\r
+ * permission. This software is supplied as is without expressed or\r
+ * implied warranties of any kind.\r
+ *\r
+ *     Research Systems Unix Group\r
+ *     The University of Michigan\r
+ *     c/o Mike Clark\r
+ *     535 W. William Street\r
+ *     Ann Arbor, Michigan\r
+ *     +1-313-763-0525\r
+ *     netatalk@itd.umich.edu\r
+ */\r
+\r
+#ifndef __AT_HEADER__\r
+#define __AT_HEADER__\r
+/*\r
+ * Supported protocols\r
+ */\r
+#define ATPROTO_DDP    0\r
+#define ATPROTO_AARP   254\r
+\r
+/*\r
+ * Ethernet types, for DIX.\r
+ * These should really be in some global header file, but we can't\r
+ * count on them being there, and it's annoying to patch system files.\r
+ */\r
+#define ETHERTYPE_AT   0x809B          /* AppleTalk protocol */\r
+#define ETHERTYPE_AARP 0x80F3          /* AppleTalk ARP */\r
+\r
+#define DDP_MAXSZ      587\r
+\r
+/*\r
+ * If ATPORT_FIRST <= Port < ATPORT_RESERVED,\r
+ * Port was created by a privileged process.\r
+ * If ATPORT_RESERVED <= Port < ATPORT_LAST,\r
+ * Port was not necessarily created by a\r
+ * privileged process.\r
+ */\r
+#define ATPORT_FIRST   1\r
+#define ATPORT_RESERVED        128\r
+#define ATPORT_LAST    255\r
+\r
+/*\r
+ * AppleTalk address.\r
+ */\r
+struct at_addr {\r
+    u_short    s_net;\r
+    u_char     s_node;\r
+};\r
+\r
+#define ATADDR_ANYNET  (u_short)0x0000\r
+#define ATADDR_ANYNODE (u_char)0x00\r
+#define ATADDR_ANYPORT (u_char)0x00\r
+#define ATADDR_BCAST   (u_char)0xff            /* There is no BCAST for NET */\r
+\r
+struct netrange {\r
+    u_char             nr_phase;\r
+    u_short            nr_firstnet;\r
+    u_short            nr_lastnet;\r
+};\r
+\r
+/*\r
+ * Socket address, AppleTalk style.  We keep magic information in the \r
+ * zero bytes.  There are three types, NONE, CONFIG which has the phase\r
+ * and a net range, and IFACE which has the network address of an\r
+ * interface.  IFACE may be filled in by the client, and is filled in\r
+ * by the kernel.\r
+ */\r
+struct sockaddr_at {\r
+    u_char             sat_len;\r
+    u_char             sat_family;\r
+    u_char             sat_port;\r
+    struct at_addr     sat_addr;\r
+    union {\r
+       struct netrange r_netrange;\r
+       char            r_zero[ 8 ];    /* Hide a struct netrange in here */\r
+    } sat_range;\r
+};\r
+\r
+#define sat_zero sat_range.r_zero\r
+\r
+#endif /* !__AT_HEADER__ */\r
index e645f77bd3e8ce212341fc753a6b9fbd12ebd57c..e0d1a820823c0d66ae2de913622d3232dabda0dc 100644 (file)
@@ -94,6 +94,7 @@
 #include <sys/cdefs.h>\r
 #include <sys/featuretest.h>\r
 #include <inttypes.h>\r
+#include <paths.h>\r
 /*\r
  * Data types\r
  */\r
@@ -108,27 +109,6 @@ typedef __socklen_t        socklen_t;
   #undef _BSD_SIZE_T_\r
 #endif\r
 \r
-////#if defined(_NETBSD_SOURCE)\r
-////#ifndef _PATH_HEQUIV\r
-////#define    _PATH_HEQUIV    "/etc/hosts.equiv"\r
-////#endif\r
-#ifndef _PATH_HOSTS\r
-#define        _PATH_HOSTS     "/etc/hosts"\r
-#endif\r
-#ifndef _PATH_NETWORKS\r
-#define        _PATH_NETWORKS  "/etc/networks"\r
-#endif\r
-#ifndef _PATH_PROTOCOLS\r
-#define        _PATH_PROTOCOLS "/etc/protocols"\r
-#endif\r
-#ifndef _PATH_SERVICES\r
-#define        _PATH_SERVICES  "/etc/services"\r
-#endif\r
-////#ifndef _PATH_SERVICES_DB\r
-////#define    _PATH_SERVICES_DB "/var/db/services.db"\r
-////#endif\r
-////#endif\r
-\r
 __BEGIN_DECLS\r
 extern int h_errno;\r
 __END_DECLS\r
@@ -219,14 +199,11 @@ struct addrinfo {
 #define        NETDB_INTERNAL  -1      /*%< see errno */\r
 #define        NETDB_SUCCESS   0       /*%< no problem */\r
 #endif\r
-////#define    NO_ADDRESS      NO_DATA         /* no address, look for MX record */\r
+#define        NO_ADDRESS      NO_DATA         /* no address, look for MX record */\r
 #define        HOST_NOT_FOUND  1 /*%< Authoritative Answer Host not found */\r
 #define        TRY_AGAIN       2 /*%< Non-Authoritive Host not found, or SERVERFAIL */\r
 #define        NO_RECOVERY     3 /*%< Non recoverable errors, FORMERR, REFUSED, NOTIMP */\r
-////#define    NO_DATA         4 /*%< Valid name, no data record of requested type */\r
-////#if defined(_NETBSD_SOURCE)\r
-////#define    NO_ADDRESS      NO_DATA         /*%< no address, look for MX record */\r
-////#endif\r
+#define        NO_DATA         4 /*%< Valid name, no data record of requested type */\r
 \r
 /*\r
  * Error return codes from getaddrinfo()\r
diff --git a/StdLib/Include/netinet/in_systm.h b/StdLib/Include/netinet/in_systm.h
new file mode 100644 (file)
index 0000000..f86bf65
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+ * Copyright (c) 1982, 1986, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)in_systm.h  8.1 (Berkeley) 6/10/93\r
+ * $Id: in_systm.h,v 1.1.1.1 2006/05/30 06:12:48 hhzhou Exp $\r
+ */\r
+\r
+#ifndef _NETINET_IN_SYSTM_H_\r
+#define _NETINET_IN_SYSTM_H_\r
+\r
+/*\r
+ * Miscellaneous internetwork\r
+ * definitions for kernel.\r
+ */\r
+\r
+/*\r
+ * Network types.\r
+ *\r
+ * Internally the system keeps counters in the headers with the bytes\r
+ * swapped so that VAX instructions will work on them.  It reverses\r
+ * the bytes before transmission at each protocol level.  The n_ types\r
+ * represent the types with the bytes in ``high-ender'' order.\r
+ */\r
+typedef u_int16_t n_short;             /* short as received from the net */\r
+typedef u_int32_t n_long;              /* long as received from the net */\r
+\r
+typedef        u_int32_t n_time;               /* ms since 00:00 GMT, byte rev */\r
+\r
+#ifdef KERNEL\r
+n_time  iptime __P((void));\r
+#endif\r
+\r
+#endif\r
diff --git a/StdLib/Include/netinet/ip.h b/StdLib/Include/netinet/ip.h
new file mode 100644 (file)
index 0000000..b2de1b9
--- /dev/null
@@ -0,0 +1,197 @@
+/*\r
+ * Copyright (c) 1982, 1986, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ * \r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ *     @(#)ip.h        8.2 (Berkeley) 6/1/94\r
+ *     $Id: ip.h,v 1.1.1.1 2006/05/30 06:12:48 hhzhou Exp $\r
+ */\r
+\r
+#ifndef _NETINET_IP_H_\r
+#define _NETINET_IP_H_\r
+\r
+#ifndef _ORG_FREEBSD_\r
+#define _IP_VHL\r
+#endif\r
+\r
+/*\r
+ * Definitions for internet protocol version 4.\r
+ * Per RFC 791, September 1981.\r
+ */\r
+#define        IPVERSION       4\r
+\r
+/*\r
+ * Structure of an internet header, naked of options.\r
+ */\r
+struct ip {\r
+#ifdef _IP_VHL\r
+       u_char  ip_vhl;                 /* version << 4 | header length >> 2 */\r
+#else\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+       u_int   ip_hl:4,                /* header length */\r
+               ip_v:4;                 /* version */\r
+#endif\r
+#if BYTE_ORDER == BIG_ENDIAN\r
+       u_int   ip_v:4,                 /* version */\r
+               ip_hl:4;                /* header length */\r
+#endif\r
+#endif /* not _IP_VHL */\r
+       u_char  ip_tos;                 /* type of service */\r
+       u_short ip_len;                 /* total length */\r
+       u_short ip_id;                  /* identification */\r
+       u_short ip_off;                 /* fragment offset field */\r
+#define        IP_RF 0x8000                    /* reserved fragment flag */\r
+#define        IP_DF 0x4000                    /* dont fragment flag */\r
+#define        IP_MF 0x2000                    /* more fragments flag */\r
+#define        IP_OFFMASK 0x1fff               /* mask for fragmenting bits */\r
+       u_char  ip_ttl;                 /* time to live */\r
+       u_char  ip_p;                   /* protocol */\r
+       u_short ip_sum;                 /* checksum */\r
+       struct  in_addr ip_src,ip_dst;  /* source and dest address */\r
+};\r
+\r
+#ifdef _IP_VHL\r
+#define        IP_MAKE_VHL(v, hl)      ((v) << 4 | (hl))\r
+#define        IP_VHL_HL(vhl)          ((vhl) & 0x0f)\r
+#define        IP_VHL_V(vhl)           ((vhl) >> 4)\r
+#define        IP_VHL_BORING           0x45\r
+#endif\r
+\r
+#define        IP_MAXPACKET    65535           /* maximum packet size */\r
+\r
+/*\r
+ * Definitions for IP type of service (ip_tos)\r
+ */\r
+#define        IPTOS_LOWDELAY          0x10\r
+#define        IPTOS_THROUGHPUT        0x08\r
+#define        IPTOS_RELIABILITY       0x04\r
+#define        IPTOS_MINCOST           0x02\r
+\r
+/*\r
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)\r
+ */\r
+#define        IPTOS_PREC_NETCONTROL           0xe0\r
+#define        IPTOS_PREC_INTERNETCONTROL      0xc0\r
+#define        IPTOS_PREC_CRITIC_ECP           0xa0\r
+#define        IPTOS_PREC_FLASHOVERRIDE        0x80\r
+#define        IPTOS_PREC_FLASH                0x60\r
+#define        IPTOS_PREC_IMMEDIATE            0x40\r
+#define        IPTOS_PREC_PRIORITY             0x20\r
+#define        IPTOS_PREC_ROUTINE              0x00\r
+\r
+/*\r
+ * Definitions for options.\r
+ */\r
+#define        IPOPT_COPIED(o)         ((o)&0x80)\r
+#define        IPOPT_CLASS(o)          ((o)&0x60)\r
+#define        IPOPT_NUMBER(o)         ((o)&0x1f)\r
+\r
+#define        IPOPT_CONTROL           0x00\r
+#define        IPOPT_RESERVED1         0x20\r
+#define        IPOPT_DEBMEAS           0x40\r
+#define        IPOPT_RESERVED2         0x60\r
+\r
+#define        IPOPT_EOL               0               /* end of option list */\r
+#define        IPOPT_NOP               1               /* no operation */\r
+\r
+#define        IPOPT_RR                7               /* record packet route */\r
+#define        IPOPT_TS                68              /* timestamp */\r
+#define        IPOPT_SECURITY          130             /* provide s,c,h,tcc */\r
+#define        IPOPT_LSRR              131             /* loose source route */\r
+#define        IPOPT_SATID             136             /* satnet id */\r
+#define        IPOPT_SSRR              137             /* strict source route */\r
+#define        IPOPT_RA                148             /* router alert */\r
+\r
+/*\r
+ * Offsets to fields in options other than EOL and NOP.\r
+ */\r
+#define        IPOPT_OPTVAL            0               /* option ID */\r
+#define        IPOPT_OLEN              1               /* option length */\r
+#define IPOPT_OFFSET           2               /* offset within option */\r
+#define        IPOPT_MINOFF            4               /* min value of above */\r
+\r
+/*\r
+ * Time stamp option structure.\r
+ */\r
+struct ip_timestamp {\r
+       u_char  ipt_code;               /* IPOPT_TS */\r
+       u_char  ipt_len;                /* size of structure (variable) */\r
+       u_char  ipt_ptr;                /* index of current entry */\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+       u_int   ipt_flg:4,              /* flags, see below */\r
+               ipt_oflw:4;             /* overflow counter */\r
+#endif\r
+#if BYTE_ORDER == BIG_ENDIAN\r
+       u_int   ipt_oflw:4,             /* overflow counter */\r
+               ipt_flg:4;              /* flags, see below */\r
+#endif\r
+       union ipt_timestamp {\r
+               n_long  ipt_time[1];\r
+               struct  ipt_ta {\r
+                       struct in_addr ipt_addr;\r
+                       n_long ipt_time;\r
+               } ipt_ta[1];\r
+       } ipt_timestamp;\r
+};\r
+\r
+/* flag bits for ipt_flg */\r
+#define        IPOPT_TS_TSONLY         0               /* timestamps only */\r
+#define        IPOPT_TS_TSANDADDR      1               /* timestamps and addresses */\r
+#define        IPOPT_TS_PRESPEC        3               /* specified modules only */\r
+\r
+/* bits for security (not byte swapped) */\r
+#define        IPOPT_SECUR_UNCLASS     0x0000\r
+#define        IPOPT_SECUR_CONFID      0xf135\r
+#define        IPOPT_SECUR_EFTO        0x789a\r
+#define        IPOPT_SECUR_MMMM        0xbc4d\r
+#define        IPOPT_SECUR_RESTR       0xaf13\r
+#define        IPOPT_SECUR_SECRET      0xd788\r
+#define        IPOPT_SECUR_TOPSECRET   0x6bc5\r
+\r
+/*\r
+ * Internet implementation parameters.\r
+ */\r
+#define        MAXTTL          255             /* maximum time to live (seconds) */\r
+#define        IPDEFTTL        64              /* default ttl, from RFC 1340 */\r
+#define        IPFRAGTTL       60              /* time to live for frags, slowhz */\r
+#define        IPTTLDEC        1               /* subtracted when forwarding */\r
+\r
+#define        IP_MSS          576             /* default maximum segment size */\r
+\r
+#endif\r
diff --git a/StdLib/Include/netns/ns.h b/StdLib/Include/netns/ns.h
new file mode 100644 (file)
index 0000000..58bac08
--- /dev/null
@@ -0,0 +1,157 @@
+/*\r
+ * Copyright (c) 1984, 1985, 1986, 1987, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)ns.h        8.1 (Berkeley) 6/10/93\r
+ * $Id: ns.h,v 1.1.1.1 2003/11/19 01:48:56 kyu3 Exp $\r
+ */\r
+\r
+#ifndef _NETNS_NS_H_\r
+#define _NETNS_NS_H_\r
+\r
+/*\r
+ * Constants and Structures defined by the Xerox Network Software\r
+ * per "Internet Transport Protocols", XSIS 028112, December 1981\r
+ */\r
+\r
+/*\r
+ * Protocols\r
+ */\r
+#define NSPROTO_RI     1               /* Routing Information */\r
+#define NSPROTO_ECHO   2               /* Echo Protocol */\r
+#define NSPROTO_ERROR  3               /* Error Protocol */\r
+#define NSPROTO_PE     4               /* Packet Exchange */\r
+#define NSPROTO_SPP    5               /* Sequenced Packet */\r
+#define NSPROTO_RAW    255             /* Placemarker*/\r
+#define NSPROTO_MAX    256             /* Placemarker*/\r
+\r
+\r
+/*\r
+ * Port/Socket numbers: network standard functions\r
+ */\r
+\r
+#define NSPORT_RI      1               /* Routing Information */\r
+#define NSPORT_ECHO    2               /* Echo */\r
+#define NSPORT_RE      3               /* Router Error */\r
+\r
+/*\r
+ * Ports < NSPORT_RESERVED are reserved for priveleged\r
+ * processes (e.g. root).\r
+ */\r
+#define NSPORT_RESERVED                3000\r
+\r
+/* flags passed to ns_output as last parameter */\r
+\r
+#define        NS_FORWARDING           0x1     /* most of idp header exists */\r
+#define        NS_ROUTETOIF            0x10    /* same as SO_DONTROUTE */\r
+#define        NS_ALLOWBROADCAST       SO_BROADCAST    /* can send broadcast packets */\r
+\r
+#define NS_MAXHOPS             15\r
+\r
+/* flags passed to get/set socket option */\r
+#define        SO_HEADERS_ON_INPUT     1\r
+#define        SO_HEADERS_ON_OUTPUT    2\r
+#define        SO_DEFAULT_HEADERS      3\r
+#define        SO_LAST_HEADER          4\r
+#define        SO_NSIP_ROUTE           5\r
+#define SO_SEQNO               6\r
+#define        SO_ALL_PACKETS          7\r
+#define SO_MTU                 8\r
+\r
+\r
+/*\r
+ * NS addressing\r
+ */\r
+union ns_host {\r
+       u_char  c_host[6];\r
+       u_short s_host[3];\r
+};\r
+\r
+union ns_net {\r
+       u_char  c_net[4];\r
+       u_short s_net[2];\r
+};\r
+\r
+union ns_net_u {\r
+       union ns_net    net_e;\r
+       u_long          long_e;\r
+};\r
+\r
+struct ns_addr {\r
+       union ns_net    x_net;\r
+       union ns_host   x_host;\r
+       u_short x_port;\r
+};\r
+\r
+/*\r
+ * Socket address, Xerox style\r
+ */\r
+struct sockaddr_ns {\r
+       u_char          sns_len;\r
+       u_char          sns_family;\r
+       struct ns_addr  sns_addr;\r
+       char            sns_zero[2];\r
+};\r
+#define sns_port sns_addr.x_port\r
+\r
+#ifdef vax\r
+#define ns_netof(a) (*(long *) & ((a).x_net)) /* XXX - not needed */\r
+#endif\r
+#define ns_neteqnn(a,b) (((a).s_net[0]==(b).s_net[0]) && \\r
+                                       ((a).s_net[1]==(b).s_net[1]))\r
+#define ns_neteq(a,b) ns_neteqnn((a).x_net, (b).x_net)\r
+#define satons_addr(sa)        (((struct sockaddr_ns *)&(sa))->sns_addr)\r
+#define ns_hosteqnh(s,t) ((s).s_host[0] == (t).s_host[0] && \\r
+       (s).s_host[1] == (t).s_host[1] && (s).s_host[2] == (t).s_host[2])\r
+#define ns_hosteq(s,t) (ns_hosteqnh((s).x_host,(t).x_host))\r
+#define ns_nullhost(x) (((x).x_host.s_host[0]==0) && \\r
+       ((x).x_host.s_host[1]==0) && ((x).x_host.s_host[2]==0))\r
+\r
+#ifdef KERNEL\r
+extern struct domain nsdomain;\r
+union ns_host ns_thishost;\r
+union ns_host ns_zerohost;\r
+union ns_host ns_broadhost;\r
+union ns_net ns_zeronet;\r
+union ns_net ns_broadnet;\r
+u_short ns_cksum();\r
+#else\r
+\r
+#include <sys/cdefs.h>\r
+\r
+__BEGIN_DECLS\r
+extern struct ns_addr ns_addr (const char *);\r
+extern char *ns_ntoa (struct ns_addr);\r
+__END_DECLS\r
+\r
+#endif\r
+\r
+#endif\r
index 389272f0d9e820ac0be9c4cce4b5251b9ed6f0b2..d70e8dd88574e756d0b178b2f2e9d0684295bb9f 100644 (file)
 //#define _PATH_DEFPATH "/usr/bin:/bin:/usr/pkg/bin:/usr/local/bin"\r
 //#endif\r
 \r
+/*\r
+ * Provide trailing slash, since mostly used for building pathnames.\r
+ * see the __CONCAT() macro from <sys/EfiCdefs.h> for cpp examples.\r
+ */\r
+#define _PATH_DEV "/dev/"\r
+#define _PATH_ETC "/Efi/etc/"\r
+#define _PATH_TMP "/Efi/Temp/"\r
+//#define _PATH_DEV_PTS "/dev/pts/"\r
+//#define _PATH_EMUL_AOUT "/emul/aout/"\r
+//#define _PATH_VARDB "/var/db/"\r
+//#define _PATH_VARRUN  "/var/run/"\r
+//#define _PATH_VARTMP  "/var/tmp/"\r
+\r
 ///*\r
 // * All standard utilities path.\r
 // * set by init(8) for system programs & scripts (e.g. /etc/rc)\r
 #define _PATH_SOCKET  "socket:"\r
 \r
 // *nix style device paths\r
-#define _PATH_DEVTTY      "/dev/tty"\r
-#define _PATH_DEVNULL     "/dev/null"\r
-#define _PATH_DEVCONSOLE  "/dev/console"\r
-#define _PATH_DEVCONSTTY  "/dev/constty"\r
-#define _PATH_DEVSTDIN    "/dev/stdin"\r
-#define _PATH_DEVSTDOUT   "/dev/stdout"\r
-#define _PATH_DEVSTDERR   "/dev/stderr"\r
-#define _PATH_DEVSOCKET   "/dev/socket"\r
+#define _PATH_DEVTTY      _PATH_DEV "tty"\r
+#define _PATH_DEVNULL     _PATH_DEV "null"\r
+#define _PATH_DEVCONSOLE  _PATH_DEV "console"\r
+#define _PATH_DEVCONSTTY  _PATH_DEV "constty"\r
+#define _PATH_DEVSTDIN    _PATH_DEV "stdin"\r
+#define _PATH_DEVSTDOUT   _PATH_DEV "stdout"\r
+#define _PATH_DEVSTDERR   _PATH_DEV "stderr"\r
+#define _PATH_DEVSOCKET   _PATH_DEV "socket"\r
 \r
 // Special files and locations\r
-#define _PATH_HOSTS       "/Efi/etc/hosts"\r
-#define _PATH_SERVICES    "/Efi/etc/services"\r
-#define _PATH_HOSTNAME    "/Efi/etc/hostname"\r
-#define _PATH_LOCALE      "/Efi/etc/Locale"\r
-#define _PATH_FSTAB       "/Efi/etc/fstab"\r
+#define _PATH_FSTAB       _PATH_ETC "fstab"\r
+////#define _PATH_HEQUIV      _PATH_ETC "hosts.equiv"\r
+#define _PATH_HOSTNAME    _PATH_ETC "hostname"\r
+#define _PATH_HOSTS       _PATH_ETC "hosts"\r
+#define _PATH_HOSTCONF    _PATH_ETC "host.conf"\r
+#define _PATH_LOCALE      _PATH_ETC "Locale"\r
+#define _PATH_NETCONF     _PATH_ETC "host.conf"\r
+#define _PATH_NETWORKS    _PATH_ETC "networks"\r
+#define _PATH_PROTOCOLS   _PATH_ETC "protocols"\r
 \r
 /*\r
- * Provide trailing slash, since mostly used for building pathnames.\r
- * see the __CONCAT() macro from <sys/EfiCdefs.h> for cpp examples.\r
+ * Resolver configuration file.\r
+ * Normally not present, but may contain the address of the\r
+ * inital name server(s) to query and the domain search list.\r
  */\r
-#define _PATH_DEV "/dev/"\r
-#define _PATH_TMP "/Efi/Temp/"\r
-//#define _PATH_DEV_PTS "/dev/pts/"\r
-//#define _PATH_EMUL_AOUT "/emul/aout/"\r
-//#define _PATH_VARDB "/var/db/"\r
-//#define _PATH_VARRUN  "/var/run/"\r
-//#define _PATH_VARTMP  "/var/tmp/"\r
+#define _PATH_RESCONF     _PATH_ETC "resolv.conf"\r
+#define _PATH_SERVICES    _PATH_ETC "services"\r
+////#define _PATH_SERVICES_DB "/Efi/var/db/services.db"\r
 \r
 //#define _PATH_BSHELL  RESCUEDIR "/sh"\r
 //#define _PATH_CSHELL  RESCUEDIR "/csh"\r
diff --git a/StdLib/Include/pwd.h b/StdLib/Include/pwd.h
new file mode 100644 (file)
index 0000000..afbae15
--- /dev/null
@@ -0,0 +1,145 @@
+/*  $NetBSD: pwd.h,v 1.39 2005/05/24 17:36:29 kleink Exp $  */\r
+\r
+/*-\r
+ * Copyright (c) 1989, 1993\r
+ *  The Regents of the University of California.  All rights reserved.\r
+ * (c) UNIX System Laboratories, Inc.\r
+ * All or some portions of this file are derived from material licensed\r
+ * to the University of California by American Telephone and Telegraph\r
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with\r
+ * the permission of UNIX System Laboratories, Inc.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *  @(#)pwd.h 8.2 (Berkeley) 1/21/94\r
+ */\r
+\r
+/*-\r
+ * Portions Copyright(C) 1995, Jason Downs.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#ifndef _PWD_H_\r
+#define _PWD_H_\r
+\r
+#include <sys/EfiCdefs.h>\r
+#include <sys/featuretest.h>\r
+#include <sys/types.h>\r
+\r
+#define _PATH_PASSWD            "/etc/passwd"\r
+#define _PATH_MASTERPASSWD      "/etc/master.passwd"\r
+#define _PATH_MASTERPASSWD_LOCK "/etc/ptmp"\r
+\r
+#define _PATH_PASSWD_CONF       "/etc/passwd.conf"\r
+#define _PATH_PASSWDCONF        _PATH_PASSWD_CONF /* XXX: compat */\r
+#define _PATH_USERMGMT_CONF     "/etc/usermgmt.conf"\r
+\r
+#define _PATH_MP_DB             "/etc/pwd.db"\r
+#define _PATH_SMP_DB            "/etc/spwd.db"\r
+\r
+#define _PATH_PWD_MKDB          "/usr/sbin/pwd_mkdb"\r
+\r
+#define _PW_KEYBYNAME     '1' /* stored by name */\r
+#define _PW_KEYBYNUM      '2' /* stored by entry in the "file" */\r
+#define _PW_KEYBYUID      '3' /* stored by uid */\r
+\r
+#define _PASSWORD_EFMT1   '_' /* extended DES encryption format */\r
+#define _PASSWORD_NONDES  '$' /* non-DES encryption formats */\r
+\r
+#define _PASSWORD_LEN     128 /* max length, not counting NUL */\r
+\r
+#define _PASSWORD_NOUID   0x01  /* flag for no specified uid. */\r
+#define _PASSWORD_NOGID   0x02  /* flag for no specified gid. */\r
+#define _PASSWORD_NOCHG   0x04  /* flag for no specified change. */\r
+#define _PASSWORD_NOEXP   0x08  /* flag for no specified expire. */\r
+\r
+#define _PASSWORD_OLDFMT  0x10  /* flag to expect an old style entry */\r
+#define _PASSWORD_NOWARN  0x20  /* no warnings for bad entries */\r
+\r
+#define _PASSWORD_WARNDAYS  14  /* days to warn about expiry */\r
+#define _PASSWORD_CHGNOW    -1  /* special day to force password\r
+                                 * change at next login */\r
+\r
+struct passwd {\r
+  __aconst char    *pw_name;    /* user name */\r
+  __aconst char    *pw_passwd;  /* encrypted password */\r
+  uid_t             pw_uid;     /* user uid */\r
+  gid_t             pw_gid;     /* user gid */\r
+  time_t            pw_change;  /* password change time */\r
+  __aconst char    *pw_class;   /* user login class */\r
+  __aconst char    *pw_gecos;   /* general information */\r
+  __aconst char    *pw_dir;     /* home directory */\r
+  __aconst char    *pw_shell;   /* default shell */\r
+  time_t            pw_expire;  /* account expiration */\r
+};\r
+\r
+__BEGIN_DECLS\r
+  struct passwd    *getpwuid(uid_t);\r
+  struct passwd    *getpwnam(const char *);\r
+\r
+#if 0   /* Normally declared here but not implemented for UEFI. */\r
+\r
+  int               getpwnam_r( const char *, struct passwd *, char *, size_t,\r
+                                struct passwd **);\r
+  int               getpwuid_r( uid_t, struct passwd *, char *, size_t,\r
+                                struct passwd **);\r
+\r
+  struct passwd    *getpwent(void);\r
+  void              setpwent(void);\r
+  void              endpwent(void);\r
+\r
+  int               pw_gensalt(char *, size_t, const char *, const char *);\r
+  int               pw_scan(char *, struct passwd *, int *);\r
+  int               setpassent(int);\r
+  int               getpwent_r(struct passwd *, char *, size_t, struct passwd **);\r
+  const char       *user_from_uid(uid_t, int);\r
+  int               uid_from_user(const char *, uid_t *);\r
+  int               pwcache_userdb( int (*)(int), void (*)(void),\r
+                                    struct passwd * (*)(const char *),\r
+                                    struct passwd * (*)(uid_t));\r
+#endif\r
+__END_DECLS\r
+\r
+#endif /* !_PWD_H_ */\r
diff --git a/StdLib/Include/resolv.h b/StdLib/Include/resolv.h
new file mode 100644 (file)
index 0000000..818a0ea
--- /dev/null
@@ -0,0 +1,293 @@
+/*-\r
+ * Copyright (c) 1983, 1987, 1989, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+/*\r
+ * Portions Copyright (c) 1996 by Internet Software Consortium.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ *     @(#)resolv.h    8.1 (Berkeley) 6/2/93\r
+ *     From Id: resolv.h,v 8.12 1998/04/28 19:36:46 halley Exp $\r
+ *     $Id: resolv.h,v 1.1.1.1 2003/11/19 01:48:35 kyu3 Exp $\r
+ */\r
+\r
+#ifndef _RESOLV_H_\r
+#define        _RESOLV_H_\r
+\r
+#include <arpa/nameser.h>\r
+#include <sys/param.h>\r
+#include <sys/types.h>\r
+#include <sys/cdefs.h>\r
+#include <stdio.h>\r
+#include <paths.h>\r
+\r
+#ifndef __P\r
+#define __P(x)      x\r
+#endif  //  __P\r
+\r
+/*\r
+ * Revision information.  This is the release date in YYYYMMDD format.\r
+ * It can change every day so the right thing to do with it is use it\r
+ * in preprocessor commands such as "#if (__RES > 19931104)".  Do not\r
+ * compare for equality; rather, use it to determine whether your resolver\r
+ * is new enough to contain a certain feature.\r
+ */\r
+\r
+#define        __RES   19960801\r
+\r
+/*\r
+ * Global defines and variables for resolver stub.\r
+ */\r
+#define        MAXNS                   3       /* max # name servers we'll track */\r
+#define        MAXDFLSRCH              3       /* # default domain levels to try */\r
+#define        MAXDNSRCH               6       /* max # domains in search path */\r
+#define        LOCALDOMAINPARTS        2       /* min levels in name that is "local" */\r
+\r
+#define        RES_TIMEOUT             5       /* min. seconds between retries */\r
+#define        MAXRESOLVSORT           10      /* number of net to sort on */\r
+#define        RES_MAXNDOTS            15      /* should reflect bit field size */\r
+\r
+struct __res_state {\r
+       int     retrans;                /* retransmition time interval */\r
+       int     retry;                  /* number of times to retransmit */\r
+       u_long  options;                /* option flags - see below. */\r
+       int     nscount;                /* number of name servers */\r
+       struct sockaddr_in\r
+               nsaddr_list[MAXNS];     /* address of name server */\r
+#define        nsaddr  nsaddr_list[0]          /* for backward compatibility */\r
+       u_short id;                     /* current message id */\r
+       char    *dnsrch[MAXDNSRCH+1];   /* components of domain to search */\r
+       char    defdname[256];          /* default domain (deprecated) */\r
+       u_long  pfcode;                 /* RES_PRF_ flags - see below. */\r
+       unsigned ndots:4;               /* threshold for initial abs. query */\r
+       unsigned nsort:4;               /* number of elements in sort_list[] */\r
+       char    unused[3];\r
+       struct {\r
+               struct in_addr  addr;\r
+               u_int32_t       mask;\r
+       } sort_list[MAXRESOLVSORT];\r
+       char    pad[72];                /* on an i386 this means 512b total */\r
+};\r
+\r
+/*\r
+ * Resolver options (keep these in synch with res_debug.c, please)\r
+ */\r
+#define RES_INIT       0x00000001      /* address initialized */\r
+#define RES_DEBUG      0x00000002      /* print debug messages */\r
+#define RES_AAONLY     0x00000004      /* authoritative answers only (!IMPL)*/\r
+#define RES_USEVC      0x00000008      /* use virtual circuit */\r
+#define RES_PRIMARY    0x00000010      /* query primary server only (!IMPL) */\r
+#define RES_IGNTC      0x00000020      /* ignore truncation errors */\r
+#define RES_RECURSE    0x00000040      /* recursion desired */\r
+#define RES_DEFNAMES   0x00000080      /* use default domain name */\r
+#define RES_STAYOPEN   0x00000100      /* Keep TCP socket open */\r
+#define RES_DNSRCH     0x00000200      /* search up local domain tree */\r
+#define        RES_INSECURE1   0x00000400      /* type 1 security disabled */\r
+#define        RES_INSECURE2   0x00000800      /* type 2 security disabled */\r
+#define        RES_NOALIASES   0x00001000      /* shuts off HOSTALIASES feature */\r
+#define        RES_USE_INET6   0x00002000      /* use/map IPv6 in gethostbyname() */\r
+#define        RES_NOTLDQUERY  0x00004000      /* Don't query TLD names */\r
+\r
+#define RES_DEFAULT    (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)\r
+\r
+/*\r
+ * Resolver "pfcode" values.  Used by dig.\r
+ */\r
+#define        RES_PRF_STATS   0x00000001\r
+#define        RES_PRF_UPDATE  0x00000002\r
+#define        RES_PRF_CLASS   0x00000004\r
+#define        RES_PRF_CMD     0x00000008\r
+#define        RES_PRF_QUES    0x00000010\r
+#define        RES_PRF_ANS     0x00000020\r
+#define        RES_PRF_AUTH    0x00000040\r
+#define        RES_PRF_ADD     0x00000080\r
+#define        RES_PRF_HEAD1   0x00000100\r
+#define        RES_PRF_HEAD2   0x00000200\r
+#define        RES_PRF_TTLID   0x00000400\r
+#define        RES_PRF_HEADX   0x00000800\r
+#define        RES_PRF_QUERY   0x00001000\r
+#define        RES_PRF_REPLY   0x00002000\r
+#define        RES_PRF_INIT    0x00004000\r
+/*                     0x00008000      */\r
+\r
+typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }\r
+       res_sendhookact;\r
+\r
+typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns,\r
+                                             const u_char **query,\r
+                                             int *querylen,\r
+                                             u_char *ans,\r
+                                             int anssiz,\r
+                                             int *resplen));\r
+\r
+typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns,\r
+                                             const u_char *query,\r
+                                             int querylen,\r
+                                             u_char *ans,\r
+                                             int anssiz,\r
+                                             int *resplen));\r
+\r
+struct res_sym {\r
+       int     number;         /* Identifying number, like T_MX */\r
+       char *  name;           /* Its symbolic name, like "MX" */\r
+       char *  humanname;      /* Its fun name, like "mail exchanger" */\r
+};\r
+\r
+extern struct __res_state _res;\r
+extern const struct res_sym __p_class_syms[];\r
+extern const struct res_sym __p_type_syms[];\r
+\r
+/* Private routines shared between libc/net, named, nslookup and others. */\r
+#define        res_hnok        __res_hnok\r
+#define        res_ownok       __res_ownok\r
+#define        res_mailok      __res_mailok\r
+#define        res_dnok        __res_dnok\r
+#define        sym_ston        __sym_ston\r
+#define        sym_ntos        __sym_ntos\r
+#define        sym_ntop        __sym_ntop\r
+#define        b64_ntop        __b64_ntop\r
+#define        b64_pton        __b64_pton\r
+#define        loc_ntoa        __loc_ntoa\r
+#define        loc_aton        __loc_aton\r
+#define        fp_resstat      __fp_resstat\r
+#define        p_query         __p_query\r
+#define        dn_skipname     __dn_skipname\r
+#define        fp_resstat      __fp_resstat\r
+#define        fp_query        __fp_query\r
+#define        fp_nquery       __fp_nquery\r
+#define        hostalias       __hostalias\r
+#define        putlong         __putlong\r
+#define        putshort        __putshort\r
+#define        p_class         __p_class\r
+#define        p_time          __p_time\r
+#define        p_type          __p_type\r
+#define        p_query         __p_query\r
+#define        p_cdnname       __p_cdnname\r
+#define        p_section       __p_section\r
+#define        p_cdname        __p_cdname\r
+#define        p_fqnname       __p_fqnname\r
+#define        p_fqname        __p_fqname\r
+#define        p_option        __p_option\r
+#define        p_secstodate    __p_secstodate\r
+#define        dn_count_labels __dn_count_labels\r
+#define        dn_comp         __dn_comp\r
+#define        dn_expand       __dn_expand\r
+#define        res_init        __res_init\r
+#define        res_randomid    __res_randomid\r
+#define        res_query       __res_query\r
+#define        res_search      __res_search\r
+#define        res_querydomain __res_querydomain\r
+#define        res_mkquery     __res_mkquery\r
+#define        res_send        __res_send\r
+#define        res_isourserver __res_isourserver\r
+#define        res_nameinquery __res_nameinquery\r
+#define        res_queriesmatch __res_queriesmatch\r
+#define        res_close       __res_close\r
+#define        res_mkupdate    __res_mkupdate\r
+#define        res_mkupdrec    __res_mkupdrec\r
+#define        res_freeupdrec  __res_freeupdrec\r
+\r
+__BEGIN_DECLS\r
+int            res_hnok __P((const char *));\r
+int            res_ownok __P((const char *));\r
+int            res_mailok __P((const char *));\r
+int            res_dnok __P((const char *));\r
+int            sym_ston __P((const struct res_sym *, const char *, int *));\r
+const char *   sym_ntos __P((const struct res_sym *, int, int *));\r
+const char *   sym_ntop __P((const struct res_sym *, int, int *));\r
+int            b64_ntop __P((u_char const *, size_t, char *, size_t));\r
+int            b64_pton __P((char const *, u_char *, size_t));\r
+int            loc_aton __P((const char *, u_char *));\r
+const char *   loc_ntoa __P((const u_char *, char *));\r
+int            dn_skipname __P((const u_char *, const u_char *));\r
+void           fp_resstat __P((struct __res_state *, FILE *));\r
+void           fp_query __P((const u_char *, FILE *));\r
+void           fp_nquery __P((const u_char *, int, FILE *));\r
+const char *   hostalias __P((const char *));\r
+void           putlong __P((u_int32_t, u_char *));\r
+void           putshort __P((u_int16_t, u_char *));\r
+const char *   p_class __P((int));\r
+const char *   p_time __P((u_int32_t));\r
+const char *   p_type __P((int));\r
+void           p_query __P((const u_char *));\r
+const u_char * p_cdnname __P((const u_char *, const u_char *, int, FILE *));\r
+const u_char * p_cdname __P((const u_char *, const u_char *, FILE *));\r
+const u_char * p_fqnname __P((const u_char *, const u_char *,\r
+                              int, char *, int));\r
+const u_char * p_fqname __P((const u_char *, const u_char *, FILE *));\r
+const char *   p_option __P((u_long));\r
+char *         p_secstodate __P((u_long));\r
+int            dn_count_labels __P((const char *));\r
+int            dn_comp __P((const char *, u_char *, int,\r
+                            u_char **, u_char **));\r
+int            dn_expand __P((const u_char *, const u_char *, const u_char *,\r
+                              char *, int));\r
+int            res_init __P((void));\r
+u_int          res_randomid __P((void));\r
+int            res_query __P((const char *, int, int, u_char *, int));\r
+int            res_search __P((const char *, int, int, u_char *, int));\r
+int            res_querydomain __P((const char *, const char *, int, int,\r
+                                    u_char *, int));\r
+int            res_mkquery __P((int, const char *, int, int, const u_char *,\r
+                                int, const u_char *, u_char *, int));\r
+int            res_send __P((const u_char *, int, u_char *, int));\r
+int            res_isourserver __P((const struct sockaddr_in *));\r
+int            res_nameinquery __P((const char *, int, int,\r
+                                    const u_char *, const u_char *));\r
+int            res_queriesmatch __P((const u_char *, const u_char *,\r
+                                     const u_char *, const u_char *));\r
+void           res_close __P((void));\r
+const char *   p_section __P((int, int));\r
+/* XXX The following depend on the ns_updrec typedef in arpa/nameser.h */\r
+#ifdef _ARPA_NAMESER_H_\r
+int            res_update __P((ns_updrec *));\r
+int            res_mkupdate __P((ns_updrec *, u_char *, int));\r
+ns_updrec *    res_mkupdrec __P((int, const char *, u_int, u_int, u_long));\r
+void           res_freeupdrec __P((ns_updrec *));\r
+#endif\r
+__END_DECLS\r
+\r
+#endif /* !_RESOLV_H_ */\r
index a84369f31059263d10b17addf5d052d5b905cd64..6c1ff1b4e4b5287181b745afb16d71d71b1c7cc5 100644 (file)
@@ -14,7 +14,7 @@
   their semantics, and their default handling is implementation-defined; all\r
   signal numbers shall be positive.\r
 \r
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed and made available under\r
 the terms and conditions of the BSD License that accompanies this distribution.\r
 The full text of the license may be found at\r
@@ -57,6 +57,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define SIGSEGV    __SigSegv    ///< an invalid access to storage\r
 #define SIGTERM    __SigTerm    ///< a termination request sent to the program\r
 #define SIGBREAK   __SigBreak   ///< added for Python\r
+#define SIGALRM    __SigAlrm    ///< Added for Posix timer functions\r
+#define SIGVTALRM  __SigVtAlrm  ///< Added for Posix timer functions\r
+#define SIGPROF    __SigProf    ///< Added for Posix timer functions\r
+#define SIGUSR1    __SigUsr1    ///< Added for Posix timer functions\r
+#define SIGUSR2    __SigUsr2    ///< Added for Posix timer functions\r
+#define SIGWINCH   __SigWinch   ///< Added for Posix timer functions\r
+#define SIGPIPE    __SigPipe    ///< Added for Posix timer functions\r
+#define SIGQUIT    __SigQuit    ///< Added for Posix timer functions\r
 #define SIG_LAST   __Sig_Last   ///< One more than the largest signal number\r
 \r
 __BEGIN_DECLS\r
index 226e3156951bdc0dd63524f47f4a72113aeb73cc..b966a5ce2b24016d43e96d2afa5c56884028e20a 100644 (file)
@@ -41,10 +41,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 /** The type va_list is a type suitable for holding information needed by the\r
     macros va_start, va_arg, and va_end.\r
-\r
-    This implementation aliases va_list to VA_LIST, declared in MdePkg/Base.h.\r
 **/\r
+#if defined(__GNUC__)\r
+typedef __builtin_va_list   va_list;\r
+#else\r
 #define va_list   VA_LIST\r
+#endif\r
 \r
 /** The va_start macro shall be invoked before any access to the unnamed arguments.\r
     The va_start macro initializes ap for subsequent use by va_arg and va_end.\r
@@ -63,11 +65,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
                     is not compatible with the type that results after\r
                     application of the default argument promotions, the\r
                     behavior is undefined.\r
-\r
-    This implementation aliases va_start to VA_START, declared in MdePkg/Base.h.\r
 **/\r
-//#define va_start(ap, ParamN)    VA_START(ap, ParamN)\r
+#if defined(__GNUC__)\r
+#define va_start    __builtin_va_start\r
+#else\r
 #define va_start    VA_START\r
+#endif\r
 \r
 /** The va_arg macro expands to an expression that has the type and value of\r
     the next argument in the call.  The parameter ap shall be the same as the\r
@@ -90,11 +93,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
                   va_start macro returns the value of the argument after that\r
                   specified by paramN.  Successive invocations return the values\r
                   of the remaining arguments in succession.\r
-\r
-    This implementation aliases va_arg to VA_ARG, declared in MdePkg/Base.h.\r
 **/\r
-//#define va_arg(ap, type)        VA_ARG(ap, type)\r
+#if defined(__GNUC__)\r
+#define va_arg        __builtin_va_arg\r
+#else\r
 #define va_arg        VA_ARG\r
+#endif\r
 \r
 /** The va_end macro facillitates a normal return from the function whose\r
     variable argument list was referred to by the expansion of va_start that\r
@@ -109,13 +113,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
     @param  ap    An object of type va_list, initialized by a prior\r
                   invocation of va_start, that will no longer be referenced.\r
-\r
-    This implementation aliases va_end to VA_END, declared in MdePkg/Base.h.\r
 **/\r
-//#define va_end(ap)              VA_END(ap)\r
+#if defined(__GNUC__)\r
+#define va_end              __builtin_va_end\r
+#else\r
 #define va_end              VA_END\r
+#endif\r
 \r
 /** For BSD compatibility. **/\r
+#if defined(__GNUC__)\r
+#define va_copy         __builtin_va_copy\r
+#else\r
 #define va_copy(s,d)      (s) = (d)\r
+#endif\r
 \r
 #endif  /* _STDARG_H */\r
index 7a60a290acb905cc2676e1be0ae4cec6f4e483c7..7c3586c9abf19fb7622c19f81fbfbc339c030392 100644 (file)
@@ -36,7 +36,7 @@
 #ifndef _STDIO_H_\r
 #define _STDIO_H_\r
 \r
-#include  <sys/EfiCdefs.h>\r
+#include  <stdarg.h>\r
 #include  <limits.h>\r
 #include  <sys/ansi.h>\r
 #include  <machine/ansi.h>\r
@@ -475,14 +475,14 @@ int       setvbuf (FILE * __restrict, char * __restrict, int, size_t);
 int       sscanf  (const char * __restrict, const char * __restrict, ...);\r
 FILE     *tmpfile (void);\r
 int       ungetc  (int, FILE *);\r
-int       vfprintf(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_);\r
-int       vprintf (const char * __restrict, _BSD_VA_LIST_);\r
+int       vfprintf(FILE * __restrict, const char * __restrict, va_list);\r
+int       vprintf (const char * __restrict, va_list);\r
 \r
 #ifndef __AUDIT__\r
 char     *gets    (char *);\r
 int       sprintf (char * __restrict, const char * __restrict, ...);\r
 char     *tmpnam  (char *);\r
-int       vsprintf(char * __restrict, const char * __restrict, _BSD_VA_LIST_);\r
+int       vsprintf(char * __restrict, const char * __restrict, va_list);\r
 #endif\r
 \r
 #if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE)\r
@@ -531,46 +531,33 @@ __END_DECLS
 /*\r
  * Functions defined in POSIX 1003.2 and XPG2 or later.\r
  */\r
-#if (_POSIX_C_SOURCE - 0) >= 2 || (_XOPEN_SOURCE - 0) >= 2 || \\r
-    defined(_NETBSD_SOURCE)\r
-  __BEGIN_DECLS\r
+__BEGIN_DECLS\r
   int     pclose  (FILE *);\r
   FILE   *popen   (const char *, const char *);\r
-  __END_DECLS\r
-#endif\r
+__END_DECLS\r
 \r
 /*\r
  * Functions defined in ISO XPG4.2, ISO C99, POSIX 1003.1-2001 or later.\r
  */\r
-#if ((__STDC_VERSION__ - 0) >= 199901L) || \\r
-    ((_POSIX_C_SOURCE - 0) >= 200112L) || \\r
-    (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) || \\r
-    ((_XOPEN_SOURCE - 0) >= 500) || \\r
-    defined(_ISOC99_SOURCE) || defined(_NETBSD_SOURCE)\r
-  __BEGIN_DECLS\r
+__BEGIN_DECLS\r
   int     snprintf (char * __restrict, size_t, const char * __restrict, ...)\r
           __attribute__((__format__(__printf__, 3, 4)));\r
-  int     vsnprintf(char * __restrict, size_t, const char * __restrict, _BSD_VA_LIST_)\r
+  int     vsnprintf(char * __restrict, size_t, const char * __restrict, va_list)\r
           __attribute__((__format__(__printf__, 3, 0)));\r
-  __END_DECLS\r
-#endif\r
+__END_DECLS\r
 \r
 /*\r
  * Functions defined in XPG4.2.\r
  */\r
-#if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)\r
-  __BEGIN_DECLS\r
+__BEGIN_DECLS\r
   int   getw(FILE *);\r
   int   putw(int, FILE *);\r
   char *mkdtemp(char *);\r
   int   mkstemp(char *);\r
   char *mktemp(char *);\r
 \r
-  #ifndef __AUDIT__\r
     char *tempnam(const char *, const char *);\r
-  #endif\r
-  __END_DECLS\r
-#endif\r
+__END_DECLS\r
 \r
 /*\r
  * X/Open CAE Specification Issue 5 Version 2\r
@@ -588,15 +575,13 @@ __END_DECLS
 /*\r
  * Routines that are purely local.\r
  */\r
-#if defined(_NETBSD_SOURCE)\r
-\r
-  #define FPARSELN_UNESCESC 0x01\r
-  #define FPARSELN_UNESCCONT  0x02\r
-  #define FPARSELN_UNESCCOMM  0x04\r
-  #define FPARSELN_UNESCREST  0x08\r
-  #define FPARSELN_UNESCALL 0x0f\r
+#define FPARSELN_UNESCESC 0x01\r
+#define FPARSELN_UNESCCONT  0x02\r
+#define FPARSELN_UNESCCOMM  0x04\r
+#define FPARSELN_UNESCREST  0x08\r
+#define FPARSELN_UNESCALL 0x0f\r
 \r
-  __BEGIN_DECLS\r
+__BEGIN_DECLS\r
   //int     asprintf(char ** __restrict, const char * __restrict, ...)\r
   //      __attribute__((__format__(__printf__, 2, 3)));\r
   char   *fgetln(FILE * __restrict, size_t * __restrict);\r
@@ -605,33 +590,32 @@ __END_DECLS
   void    setbuffer(FILE *, char *, int);\r
   int     setlinebuf(FILE *);\r
   int     vasprintf(char ** __restrict, const char * __restrict,\r
-        _BSD_VA_LIST_)\r
+        va_list)\r
         __attribute__((__format__(__printf__, 2, 0)));\r
-  int     vscanf(const char * __restrict, _BSD_VA_LIST_)\r
+  int     vscanf(const char * __restrict, va_list)\r
         __attribute__((__format__(__scanf__, 1, 0)));\r
   int     vfscanf(FILE * __restrict, const char * __restrict,\r
-        _BSD_VA_LIST_)\r
+        va_list)\r
         __attribute__((__format__(__scanf__, 2, 0)));\r
   int     vsscanf(const char * __restrict, const char * __restrict,\r
-        _BSD_VA_LIST_)\r
+        va_list)\r
         __attribute__((__format__(__scanf__, 2, 0)));\r
   const char *fmtcheck(const char *, const char *)\r
         __attribute__((__format_arg__(2)));\r
-  __END_DECLS\r
+__END_DECLS\r
 \r
   /*\r
    * Stdio function-access interface.\r
    */\r
-  __BEGIN_DECLS\r
+__BEGIN_DECLS\r
   FILE  *funopen(const void *,\r
       int (*)(void *, char *, int),\r
       int (*)(void *, const char *, int),\r
       fpos_t (*)(void *, fpos_t, int),\r
       int (*)(void *));\r
-  __END_DECLS\r
+__END_DECLS\r
   //#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)\r
   //#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)\r
-#endif /* _NETBSD_SOURCE */\r
 \r
 /*\r
  * Functions internal to the implementation.\r
@@ -646,6 +630,7 @@ __END_DECLS
  * define function versions in the C library.\r
  */\r
 #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))\r
+\r
 #if defined(__GNUC__) && defined(__STDC__)\r
   static __inline int __sputc(int _c, FILE *_p) {\r
     if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))\r
@@ -673,33 +658,23 @@ __END_DECLS
 #define __sfileno(p)    ((p)->_file)\r
 \r
 #ifndef __lint__\r
-  #if !defined(_REENTRANT) && !defined(_PTHREADS)\r
     #define feof(p)     __sfeof(p)\r
     #define ferror(p)   __sferror(p)\r
     #define clearerr(p) __sclearerr(p)\r
 \r
     #define getc(fp)    __sgetc(fp)\r
     #define putc(x, fp) __sputc(x, fp)\r
-  #endif /* !_REENTRANT && !_PTHREADS */\r
 #endif /* __lint__ */\r
 \r
 #define getchar()   getc(stdin)\r
 #define putchar(x)  putc(x, stdout)\r
 \r
-#if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \\r
-    defined(_NETBSD_SOURCE)\r
-  #if !defined(_REENTRANT) && !defined(_PTHREADS)\r
-    #define fileno(p) __sfileno(p)\r
-  #endif /* !_REENTRANT && !_PTHREADS */\r
-#endif /* !_ANSI_SOURCE */\r
+#define fileno(p) __sfileno(p)\r
 \r
-#if (_POSIX_C_SOURCE - 0) >= 199506L || (_XOPEN_SOURCE - 0) >= 500 || \\r
-    defined(_REENTRANT) || defined(_NETBSD_SOURCE)\r
-  #define getc_unlocked(fp) __sgetc(fp)\r
-  #define putc_unlocked(x, fp)  __sputc(x, fp)\r
+#define getc_unlocked(fp) __sgetc(fp)\r
+#define putc_unlocked(x, fp)  __sputc(x, fp)\r
 \r
-  #define getchar_unlocked()  getc_unlocked(stdin)\r
-  #define putchar_unlocked(x) putc_unlocked(x, stdout)\r
-#endif /* _POSIX_C_SOURCE >= 199506 || _XOPEN_SOURCE >= 500 || _REENTRANT... */\r
+#define getchar_unlocked()  getc_unlocked(stdin)\r
+#define putchar_unlocked(x) putc_unlocked(x, stdout)\r
 \r
 #endif /* _STDIO_H_ */\r
index 2cfc9fe1ff2731bd977cd4771eadb53b78021d47..d51d4bffd28a3edd5eb0db8e641981b99412b95e 100644 (file)
@@ -91,7 +91,7 @@ __BEGIN_DECLS
 \r
     @sa signal.h\r
 **/\r
-void    abort(void);\r
+void    abort(void) __noreturn;\r
 \r
 /** The atexit function registers the function pointed to by func, to be\r
     called without arguments at normal program termination.\r
@@ -122,6 +122,10 @@ int     atexit(void (*)(void));
     status is zero, or EXIT_SUCCESS, status is returned unchanged. If the value\r
     of status is EXIT_FAILURE, EAPPLICATION is returned.\r
     Otherwise, status is returned unchanged.\r
+\r
+    While this function does not return, it can NOT be marked as "__noreturn"\r
+    without causing a warning to be emitted because the compilers can not\r
+    determine that the function truly does not return.\r
 **/\r
 void    exit(int status) __noreturn;\r
 \r
@@ -140,7 +144,7 @@ void    exit(int status) __noreturn;
     The status returned to the host environment is determined in the same way\r
     as for the exit function.\r
 **/\r
-void    _Exit(int status);\r
+void    _Exit(int status) __noreturn;\r
 \r
 /** The getenv function searches an environment list, provided by the host\r
     environment, for a string that matches the string pointed to by name.  The\r
@@ -641,6 +645,42 @@ size_t  mbstowcs(wchar_t * __restrict dest, const char * __restrict src, size_t
 **/\r
 size_t  wcstombs(char * __restrict dest, const wchar_t * __restrict src, size_t limit);\r
 \r
+/**\r
+  The realpath() function shall derive, from the pathname pointed to by \r
+  file_name, an absolute pathname that names the same file, whose resolution \r
+  does not involve '.', '..', or symbolic links. The generated pathname shall\r
+  be stored as a null-terminated string, up to a maximum of {PATH_MAX} bytes,\r
+  in the buffer pointed to by resolved_name.\r
+\r
+  If resolved_name is a null pointer, the behavior of realpath() is \r
+  implementation-defined.\r
+\r
+  @param[in] file_name            The filename to convert.\r
+  @param[in,out] resolved_name    The resultant name.\r
+\r
+  @retval NULL                    An error occured.\r
+  @return resolved_name.\r
+**/\r
+char * realpath(char *file_name, char *resolved_name);\r
+\r
+/**\r
+  The getprogname() function returns the name of the program.  If the name\r
+  has not been set yet, it will return NULL.\r
+\r
+  @retval         The name of the program.\r
+  @retval NULL    The name has not been set.\r
+**/\r
+const char * getprogname(void);\r
+\r
+/**\r
+  The setprogname() function sets the name of the program.\r
+\r
+  @param[in]        The name of the program.  This memory must be retained \r
+                    by the caller until no calls to "getprogname" will be \r
+                    called.\r
+**/\r
+void setprogname(const char *progname);\r
+\r
 __END_DECLS\r
 \r
 #endif  /* _STDLIB_H */\r
index 992ca0ba18a5d17cc3dcac7f026e1c62eb8ee438..517b9e6e98a6474e9fe12d1581973db585cd6738 100644 (file)
@@ -324,15 +324,31 @@ int     strerror_r(int, char *, size_t);
 int     strcasecmp(const char *s1, const char *s2);\r
 void   *memccpy   (void *, const void *, int, size_t);\r
 int     strncasecmp(const char *s1, const char *s2, size_t n);\r
+size_t  strlcpy(char *destination, const char *source, size_t size);\r
+size_t  strlcat(char *destination, const char *source, size_t size);\r
 \r
-// bcopy is same as memcpy but it is a void function, being used in socket lib\r
-#define bcopy(a,b,c) ( memcpy((void *)a, (void *)b, (size_t)c))\r
+// bcopy is is a void function with the src/dest arguments reversed, being used in socket lib\r
+#define bcopy(a,b,c) ( memcpy((void *)b, (const void *)a, (size_t)c))\r
 \r
 // bcmp is same as memcmp, returns 0 for successful compare, non-zero otherwise\r
 #define bcmp(a,b,c) ( memcmp((void *)a, (void *)b, (size_t)c))\r
 \r
-//strsep is the same as strtok, the only difference is for strsep the 1st parameter is a char**\r
-#define strsep(a,b) (strtok(*a,b))\r
+/*\r
+ * Get next token from string *stringp, where tokens are possibly-empty\r
+ * strings separated by characters from delim.\r
+ *\r
+ * Writes NULs into the string at *stringp to end tokens.\r
+ * delim need not remain constant from call to call.\r
+ * On return, *stringp points past the last NUL written (if there might\r
+ * be further tokens), or is NULL (if there are definitely no more tokens).\r
+ *\r
+ * If *stringp is NULL, strsep returns NULL.\r
+ */\r
+char *\r
+strsep(\r
+  register char **stringp,\r
+  register const char *delim\r
+  );\r
 \r
 __END_DECLS\r
 \r
diff --git a/StdLib/Include/stringlist.h b/StdLib/Include/stringlist.h
new file mode 100644 (file)
index 0000000..d0d9239
--- /dev/null
@@ -0,0 +1,65 @@
+/** @file contains all the stringlist types and functions.\r
+\r
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+\r
+ * Copyright (c) 1994 The NetBSD Foundation, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to The NetBSD Foundation\r
+ * by Christos Zoulas.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\r
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+       $NetBSD: stringlist.h,v 1.7 2008/04/28 20:22:54 martin Exp $\r
+**/\r
+\r
+#ifndef _STRINGLIST_H\r
+#define _STRINGLIST_H \r
+#include <sys/cdefs.h>\r
+#include <sys/types.h>\r
+\r
+/*\r
+ * Simple string list\r
+ */\r
+typedef struct _stringlist {\r
+       char    **sl_str;\r
+       size_t    sl_max;\r
+       size_t    sl_cur;\r
+} StringList;\r
+\r
+__BEGIN_DECLS\r
+StringList     *sl_init(void);\r
+int             sl_add(StringList *, char *);\r
+void            sl_free(StringList *, int);\r
+char           *sl_find(StringList *, const char *);\r
+int             sl_delete(StringList *, const char *, int);\r
+__END_DECLS\r
+\r
+#endif /* _STRINGLIST_H */\r
index 46aaf6e744f21ab8e212f988e884e18a9a95fdf7..c3a2772bfc202a75254fe3f18d124db573bc5204 100644 (file)
     that the library can be easily tuned for different compilers.\r
     __inline    Defined to the appropriate keyword or not defined.\r
     __func__    Defined to __FUNC__, __FUNCTION__, or NULL as appropriate.\r
-    __restrict  Defined to nothing for VC++ or to restrict for C99 compliant compilers.\r
+    __restrict  Defined to nothing for VC++ or to restrict for GCC and C99 compliant compilers.\r
 \r
     This file and its contents are inspired by the <sys/cdefs.h> files in Berkeley\r
     Unix.  They have been re-implemented to be specific to the EFI environment.\r
 \r
-    Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+    Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
     This program and the accompanying materials are licensed and made available under\r
     the terms and conditions of the BSD License that accompanies this distribution.\r
     The full text of the license may be found at\r
-    http://opensource.org/licenses/bsd-license.php.\r
+    http://opensource.org/licenses/bsd-license.\r
 \r
     THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
     WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
   #endif\r
 #endif /* !(__STDC_VERSION__ >= 199901L) */\r
 \r
-// <DVM 12/21/2010> Experiment to disable RENAME for GCC\r
-#if  0\r
-#ifdef __GNUC__\r
-  #define __RENAME(x) ___RENAME(x)\r
-#else\r
-  #ifdef __lint__\r
-    #define __RENAME(x) __symbolrename(x)\r
-  #else\r
-    /*DVM To see where this might be used... */\r
-    //#error "No function renaming possible"\r
-    #define __RENAME(x)\r
-  #endif /* __lint__ */\r
-#endif /* __GNUC__ */\r
-#else /* if 0 */\r
-  #define __RENAME(x)\r
-#endif  /* if 0 */\r
+#define __RENAME(x)\r
 \r
   /*\r
   * A barrier to stop the optimizer from moving code or assume live\r
@@ -362,6 +347,4 @@ typedef UINT32  ULONG32;
 typedef  INT64   LONG64;\r
 typedef UINT64  ULONG64;\r
 \r
-//extern int EFIAPI main();\r
-\r
 #endif  /* _EFI_CDEFS_H */\r
index 7b299108e6e7ff616068874694f29c91bc752535..a49eeda1fced66e7f04c5e9cefe785fd0b594d05 100644 (file)
@@ -75,7 +75,7 @@ int       isatty    (int);
   int     fstat     (int, struct stat *);\r
   int     lstat     (const char *, struct stat *);\r
   int     stat      (const char *, void *);\r
-//  int      chmod     (const char *, mode_t);\r
+  int     chmod     (const char *, mode_t);\r
 #endif  // __STAT_SYSCALLS_DECLARED\r
 \r
 // These are also declared in sys/types.h\r
@@ -110,10 +110,11 @@ int       FindFreeFD  (int MinFd);
 */\r
 BOOLEAN   ValidateFD (int fd, int IsOpen);\r
 \r
+char     *getcwd    (char *, size_t);\r
+int       chdir     (const char *);\r
+\r
 /* These system calls don't YET have EFI implementations. */\r
 int       access    (const char *path, int amode);\r
-int       chdir     (const char *);\r
-char     *getcwd    (char *, size_t);\r
 int       reboot    (int, char *);\r
 \r
 __END_DECLS\r
diff --git a/StdLib/Include/sys/_posix.h b/StdLib/Include/sys/_posix.h
new file mode 100644 (file)
index 0000000..706cf7e
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef _SYS__POSIX_H_\r
+#define _SYS__POSIX_H_\r
+\r
+/*-\r
+ * Copyright (c) 1998 HD Associates, Inc.\r
+ * All rights reserved.\r
+ * contact: dufault@hda.com\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     $Id: _posix.h,v 1.1.1.1 2006/05/30 06:13:04 hhzhou Exp $\r
+ */\r
+\r
+/*\r
+ * This is a stand alone header file to set up for feature specification\r
+ * defined to take place before the inclusion of any standard header.\r
+ * It should only handle pre-processor defines.\r
+ *\r
+ * See section B.2.7 of 1003.1b-1993 \r
+ *\r
+ */\r
+\r
+#ifdef KERNEL\r
+\r
+#if !defined(ACTUALLY_LKM_NOT_KERNEL) && !defined(KLD_MODULE)\r
+#include "opt_posix.h"\r
+#endif\r
+\r
+/* Only kern_mib.c uses _POSIX_VERSION.  Introduce a kernel\r
+ * one to avoid other pieces of the kernel getting dependant\r
+ * on that.\r
+ * XXX Complain if you think this dumb.\r
+ */\r
+\r
+/* Make P1003 structures visible for the kernel if\r
+ * the P1003_1B option is in effect.\r
+ */\r
+#ifdef P1003_1B\r
+#define _P1003_1B_VISIBLE\r
+#ifndef _KPOSIX_VERSION\r
+#define        _KPOSIX_VERSION         199309L\r
+#endif\r
+#endif\r
+\r
+#ifndef _KPOSIX_VERSION\r
+#define        _KPOSIX_VERSION         199009L\r
+#endif\r
+\r
+#define _P1003_1B_VISIBLE_HISTORICALLY\r
+\r
+#else\r
+\r
+/* Default to existing user space version.\r
+ */\r
+#ifndef _POSIX_VERSION\r
+#define        _POSIX_VERSION          199009L\r
+#endif\r
+\r
+/* Test for visibility of P1003.1B features:\r
+ * If _POSIX_SOURCE and POSIX_C_SOURCE are completely undefined\r
+ * they show up.\r
+ *\r
+ * If they specify a version including P1003.1B then they show up.\r
+ *\r
+ * (Two macros are added to permit hiding new extensions while \r
+ * keeping historic BSD features - that is not done now)\r
+ *\r
+ */\r
+\r
+#if (!defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)) || \\r
+ (_POSIX_VERSION  >= 199309L && defined(_POSIX_C_SOURCE) && \\r
+  _POSIX_C_SOURCE >= 199309L)\r
+#define _P1003_1B_VISIBLE\r
+#define _P1003_1B_VISIBLE_HISTORICALLY\r
+#endif\r
+\r
+#endif /* not KERNEL */\r
+#endif /* _SYS__POSIX_H_ */\r
index c7920a02b1780428f8073b4e981cd9a9f16af42c..0ce4fd9d2d5d4ee23dd24e7ffec7e945e8a186d6 100644 (file)
 #define _C_LABEL(x)   __CONCAT(_,x)\r
 #define _C_LABEL_STRING(x)  "_"x\r
 \r
-#if __STDC__\r
-#define ___RENAME(x)  __asm(___STRING(_C_LABEL(x)))\r
-#else\r
-#define ___RENAME(x)  ____RENAME(_/**/x)\r
-#define ____RENAME(x) __asm(___STRING(x))\r
-#endif\r
+#define ___RENAME(x)\r
 \r
 #define __indr_reference(sym,alias) /* nada, since we do weak refs */\r
 \r
diff --git a/StdLib/Include/sys/file.h b/StdLib/Include/sys/file.h
new file mode 100644 (file)
index 0000000..cce35f1
--- /dev/null
@@ -0,0 +1,102 @@
+/*\r
+ * Copyright (c) 1982, 1986, 1989, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *     @(#)file.h      8.3 (Berkeley) 1/9/95\r
+ * $Id: file.h,v 1.1.1.1 2006/05/30 06:12:53 hhzhou Exp $\r
+ */\r
+\r
+#ifndef _SYS_FILE_H_\r
+#define        _SYS_FILE_H_\r
+\r
+#ifndef KERNEL\r
+#include <sys/fcntl.h>\r
+#include <sys/unistd.h>\r
+#endif\r
+\r
+#ifdef KERNEL\r
+#include <sys/queue.h>\r
+\r
+struct proc;\r
+struct uio;\r
+\r
+/*\r
+ * Kernel descriptor table.\r
+ * One entry for each open kernel vnode and socket.\r
+ */\r
+struct file {\r
+       LIST_ENTRY(file) f_list;/* list of active files */\r
+       short   f_flag;         /* see fcntl.h */\r
+#define        DTYPE_VNODE     1       /* file */\r
+#define        DTYPE_SOCKET    2       /* communications endpoint */\r
+#define        DTYPE_PIPE      3       /* pipe */\r
+#define        DTYPE_FIFO      4       /* fifo (named pipe) */\r
+       short   f_type;         /* descriptor type */\r
+       short   f_count;        /* reference count */\r
+       short   f_msgcount;     /* references from message queue */\r
+       struct  ucred *f_cred;  /* credentials associated with descriptor */\r
+       struct  fileops {\r
+               int     (*fo_read)      __P((struct file *fp, struct uio *uio,\r
+                                           struct ucred *cred, int flags));\r
+               int     (*fo_write)     __P((struct file *fp, struct uio *uio,\r
+                                           struct ucred *cred, int flags));\r
+#define        FOF_OFFSET      1\r
+               int     (*fo_ioctl)     __P((struct file *fp, u_long com,\r
+                                           caddr_t data, struct proc *p));\r
+               int     (*fo_poll)      __P((struct file *fp, int events,\r
+                                           struct ucred *cred, struct proc *p));\r
+               int     (*fo_close)     __P((struct file *fp, struct proc *p));\r
+       } *f_ops;\r
+       int     f_seqcount;     /*\r
+                                * count of sequential accesses -- cleared\r
+                                * by most seek operations.\r
+                                */\r
+       off_t   f_nextread;     /*\r
+                                * offset of next expected read\r
+                                */\r
+       off_t   f_offset;\r
+       caddr_t f_data;         /* vnode or socket */\r
+};\r
+\r
+#ifdef MALLOC_DECLARE\r
+MALLOC_DECLARE(M_FILE);\r
+#endif\r
+\r
+LIST_HEAD(filelist, file);\r
+extern struct filelist filehead; /* head of list of open files */\r
+extern struct fileops vnops;\r
+extern int maxfiles;           /* kernel limit on number of open files */\r
+extern int maxfilesperproc;    /* per process limit on number of open files */\r
+extern int nfiles;             /* actual number of open files */\r
+\r
+#endif /* KERNEL */\r
+\r
+#endif /* !SYS_FILE_H */\r
index e1e5de1d5f152edfe5589a1bb2f08f66d6b6cb90..5166a0552f418f5e03cd799b06794dc1ef2d9892 100644 (file)
@@ -38,6 +38,7 @@
 #include  <sys/fd_set.h>\r
 \r
 #include  <sys/sigtypes.h>\r
+#include  <sys/time.h>\r
 #include  <time.h>\r
 \r
 __BEGIN_DECLS\r
index e945a62bfe2f8e80e6f5b6b2b86d8f79f076f5c1..6f21fcd0a2c9d6240cafddf0f04170d9aa65e25c 100644 (file)
@@ -1,5 +1,5 @@
 /**\r
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed and made available under\r
 the terms and conditions of the BSD License that accompanies this distribution.\r
 The full text of the license may be found at\r
@@ -22,6 +22,14 @@ enum {
   __SigSegv,\r
   __SigTerm,\r
   __SigBreak,\r
+  __SigAlrm,\r
+  __SigVtAlrm,\r
+  __SigProf,\r
+  __SigUsr1,\r
+  __SigUsr2,\r
+  __SigWinch,\r
+  __SigPipe,\r
+  __SigQuit,\r
   __Sig_Last\r
 };\r
 \r
diff --git a/StdLib/Include/sys/sockio.h b/StdLib/Include/sys/sockio.h
new file mode 100644 (file)
index 0000000..5711ed2
--- /dev/null
@@ -0,0 +1,100 @@
+/*-\r
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ * \r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ *     @(#)sockio.h    8.1 (Berkeley) 3/28/94\r
+ * $Id: sockio.h,v 1.1.1.1 2006/05/30 06:12:59 hhzhou Exp $\r
+ */\r
+\r
+#ifndef        _SYS_SOCKIO_H_\r
+#define        _SYS_SOCKIO_H_\r
+\r
+#include <sys/ioccom.h>\r
+\r
+/* Socket ioctl's. */\r
+#define        SIOCSHIWAT       _IOW('s',  0, int)             /* set high watermark */\r
+#define        SIOCGHIWAT       _IOR('s',  1, int)             /* get high watermark */\r
+#define        SIOCSLOWAT       _IOW('s',  2, int)             /* set low watermark */\r
+#define        SIOCGLOWAT       _IOR('s',  3, int)             /* get low watermark */\r
+#define        SIOCATMARK       _IOR('s',  7, int)             /* at oob mark? */\r
+#define        SIOCSPGRP        _IOW('s',  8, int)             /* set process group */\r
+#define        SIOCGPGRP        _IOR('s',  9, int)             /* get process group */\r
+#ifndef _ORG_FREEBSD_\r
+#define        SIOCUPCALL       _IOW('s', 10, struct upcall_req)/* register upcall req */\r
+#endif\r
+\r
+#define        SIOCADDRT        _IOW('r', 10, struct ortentry) /* add route */\r
+#define        SIOCDELRT        _IOW('r', 11, struct ortentry) /* delete route */\r
+#define        SIOCGETVIFCNT   _IOWR('r', 15, struct sioc_vif_req)/* get vif pkt cnt */\r
+#define        SIOCGETSGCNT    _IOWR('r', 16, struct sioc_sg_req) /* get s,g pkt cnt */\r
+\r
+#define        SIOCSIFADDR      _IOW('i', 12, struct ifreq)    /* set ifnet address */\r
+#define        OSIOCGIFADDR    _IOWR('i', 13, struct ifreq)    /* get ifnet address */\r
+#define        SIOCGIFADDR     _IOWR('i', 33, struct ifreq)    /* get ifnet address */\r
+#define        SIOCSIFDSTADDR   _IOW('i', 14, struct ifreq)    /* set p-p address */\r
+#define        OSIOCGIFDSTADDR _IOWR('i', 15, struct ifreq)    /* get p-p address */\r
+#define        SIOCGIFDSTADDR  _IOWR('i', 34, struct ifreq)    /* get p-p address */\r
+#define        SIOCSIFFLAGS     _IOW('i', 16, struct ifreq)    /* set ifnet flags */\r
+#define        SIOCGIFFLAGS    _IOWR('i', 17, struct ifreq)    /* get ifnet flags */\r
+#define        OSIOCGIFBRDADDR _IOWR('i', 18, struct ifreq)    /* get broadcast addr */\r
+#define        SIOCGIFBRDADDR  _IOWR('i', 35, struct ifreq)    /* get broadcast addr */\r
+#define        SIOCSIFBRDADDR   _IOW('i', 19, struct ifreq)    /* set broadcast addr */\r
+#define        OSIOCGIFCONF    _IOWR('i', 20, struct ifconf)   /* get ifnet list */\r
+#define        SIOCGIFCONF     _IOWR('i', 36, struct ifconf)   /* get ifnet list */\r
+#define        OSIOCGIFNETMASK _IOWR('i', 21, struct ifreq)    /* get net addr mask */\r
+#define        SIOCGIFNETMASK  _IOWR('i', 37, struct ifreq)    /* get net addr mask */\r
+#define        SIOCSIFNETMASK   _IOW('i', 22, struct ifreq)    /* set net addr mask */\r
+#define        SIOCGIFMETRIC   _IOWR('i', 23, struct ifreq)    /* get IF metric */\r
+#define        SIOCSIFMETRIC    _IOW('i', 24, struct ifreq)    /* set IF metric */\r
+#define        SIOCDIFADDR      _IOW('i', 25, struct ifreq)    /* delete IF addr */\r
+#define        SIOCAIFADDR      _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */\r
+\r
+#define        SIOCADDMULTI     _IOW('i', 49, struct ifreq)    /* add m'cast addr */\r
+#define        SIOCDELMULTI     _IOW('i', 50, struct ifreq)    /* del m'cast addr */\r
+#define        SIOCGIFMTU      _IOWR('i', 51, struct ifreq)    /* get IF mtu */\r
+#define        SIOCSIFMTU       _IOW('i', 52, struct ifreq)    /* set IF mtu */\r
+#define        SIOCGIFPHYS     _IOWR('i', 53, struct ifreq)    /* get IF wire */\r
+#define        SIOCSIFPHYS      _IOW('i', 54, struct ifreq)    /* set IF wire */\r
+#define        SIOCSIFMEDIA    _IOWR('i', 55, struct ifreq)    /* set net media */\r
+#define        SIOCGIFMEDIA    _IOWR('i', 56, struct ifmediareq) /* get net media */\r
+#define        SIOCSIFGENERIC   _IOW('i', 57, struct ifreq)    /* generic IF set op */\r
+#define        SIOCGIFGENERIC  _IOWR('i', 58, struct ifreq)    /* generic IF get op */\r
+\r
+#endif /* !_SYS_SOCKIO_H_ */\r
index 47e993b8bea6fc0e8ae9f24fd2b2aa5ec062df26..b87f3f12e6e2b6e2e188ef4c9968ec4e8bbe1ff2 100644 (file)
@@ -210,7 +210,7 @@ __BEGIN_DECLS
   extern int      fstat     (int, struct stat *);\r
   extern int      lstat     (const char *, struct stat *);\r
   extern int      stat      (const char *, void *);\r
-//  extern int      chmod     (const char *, mode_t);\r
+  extern int      chmod     (const char *, mode_t);\r
 #endif  // __STAT_SYSCALLS_DECLARED\r
 __END_DECLS\r
 \r
diff --git a/StdLib/Include/sys/sysctl.h b/StdLib/Include/sys/sysctl.h
new file mode 100644 (file)
index 0000000..2382900
--- /dev/null
@@ -0,0 +1,505 @@
+/*\r
+ * Copyright (c) 1989, 1993\r
+ *     The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to Berkeley by\r
+ * Mike Karels at Berkeley Software Design, Inc.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ * \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * \r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ * \r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ * \r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ * \r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ *     @(#)sysctl.h    8.1 (Berkeley) 6/2/93\r
+ * $Id: sysctl.h,v 1.1.1.1 2006/05/30 06:13:00 hhzhou Exp $\r
+ */\r
+\r
+#ifndef _SYS_SYSCTL_H_\r
+#define        _SYS_SYSCTL_H_\r
+\r
+#include <sys/_posix.h>\r
+\r
+/*\r
+ * Definitions for sysctl call.  The sysctl call uses a hierarchical name\r
+ * for objects that can be examined or modified.  The name is expressed as\r
+ * a sequence of integers.  Like a file path name, the meaning of each\r
+ * component depends on its place in the hierarchy.  The top-level and kern\r
+ * identifiers are defined here, and other identifiers are defined in the\r
+ * respective subsystem header files.\r
+ */\r
+\r
+#define CTL_MAXNAME    12      /* largest number of components supported */\r
+\r
+/*\r
+ * Each subsystem defined by sysctl defines a list of variables\r
+ * for that subsystem. Each name is either a node with further\r
+ * levels defined below it, or it is a leaf of some particular\r
+ * type given below. Each sysctl level defines a set of name/type\r
+ * pairs to be used by sysctl(1) in manipulating the subsystem.\r
+ */\r
+struct ctlname {\r
+       char    *ctl_name;      /* subsystem name */\r
+       int     ctl_type;       /* type of name */\r
+};\r
+\r
+#define CTLTYPE                0xf     /* Mask for the type */\r
+#define        CTLTYPE_NODE    1       /* name is a node */\r
+#define        CTLTYPE_INT     2       /* name describes an integer */\r
+#define        CTLTYPE_STRING  3       /* name describes a string */\r
+#define        CTLTYPE_QUAD    4       /* name describes a 64-bit number */\r
+#define        CTLTYPE_OPAQUE  5       /* name describes a structure */\r
+#define        CTLTYPE_STRUCT  CTLTYPE_OPAQUE  /* name describes a structure */\r
+\r
+#define CTLFLAG_RD     0x80000000      /* Allow reads of variable */\r
+#define CTLFLAG_WR     0x40000000      /* Allow writes to the variable */\r
+#define CTLFLAG_RW     (CTLFLAG_RD|CTLFLAG_WR)\r
+#define CTLFLAG_NOLOCK 0x20000000      /* XXX Don't Lock */\r
+#define CTLFLAG_ANYBODY        0x10000000      /* All users can set this var */\r
+#define CTLFLAG_SECURE 0x08000000      /* Permit set only if securelevel<=0 */\r
+\r
+/*\r
+ * USE THIS instead of a hardwired number from the categories below\r
+ * to get dynamically assigned sysctl entries using the linker-set\r
+ * technology. This is the way nearly all new sysctl variables should\r
+ * be implemented.\r
+ * e.g. SYSCTL_INT(_parent, OID_AUTO, name, CTLFLAG_RW, &variable, 0, "");\r
+ */ \r
+#define OID_AUTO       (-1)\r
+\r
+#ifdef KERNEL\r
+#define SYSCTL_HANDLER_ARGS (struct sysctl_oid *oidp, void *arg1, int arg2, \\r
+       struct sysctl_req *req)\r
+\r
+/*\r
+ * This describes the access space for a sysctl request.  This is needed\r
+ * so that we can use the interface from the kernel or from user-space.\r
+ */\r
+struct sysctl_req {\r
+       struct proc     *p;\r
+       int             lock;\r
+       void            *oldptr;\r
+       size_t          oldlen;\r
+       size_t          oldidx;\r
+       int             (*oldfunc)(struct sysctl_req *, const void *, size_t);\r
+       void            *newptr;\r
+       size_t          newlen;\r
+       size_t          newidx;\r
+       int             (*newfunc)(struct sysctl_req *, void *, size_t);\r
+};\r
+\r
+#ifndef _ORG_FREEBSD_\r
+#include <sys/ioccom.h>\r
+/*\r
+ *  Pseudo sysctl call through ioctl(2) interface\r
+ */\r
+#define IOCSYSCTL      _IOWR('X', 0, struct sysctl_req)\r
+\r
+struct pseudo_sysctl {\r
+       int                     *name;\r
+       u_int                   namelen;\r
+       struct sysctl_req       req;\r
+};\r
+\r
+#endif\r
+\r
+/*\r
+ * This describes one "oid" in the MIB tree.  Potentially more nodes can\r
+ * be hidden behind it, expanded by the handler.\r
+ */\r
+struct sysctl_oid {\r
+       int             oid_number;\r
+       int             oid_kind;\r
+       void            *oid_arg1;\r
+       int             oid_arg2;\r
+       const char      *oid_name;\r
+       int             (*oid_handler) SYSCTL_HANDLER_ARGS;\r
+       const char      *oid_fmt;\r
+};\r
+\r
+#define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)\r
+#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l)\r
+\r
+int sysctl_handle_int SYSCTL_HANDLER_ARGS;\r
+int sysctl_handle_long SYSCTL_HANDLER_ARGS;\r
+int sysctl_handle_intptr SYSCTL_HANDLER_ARGS;\r
+int sysctl_handle_string SYSCTL_HANDLER_ARGS;\r
+int sysctl_handle_opaque SYSCTL_HANDLER_ARGS;\r
+\r
+#ifdef _ORG_FREEBSD_\r
+/* This constructs a "raw" MIB oid. */\r
+#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \\r
+       static struct sysctl_oid sysctl__##parent##_##name = { \\r
+               nbr, kind, a1, a2, #name, handler, fmt }; \\r
+       DATA_SET(sysctl_##parent, sysctl__##parent##_##name)\r
+\r
+/* This constructs a node from which other oids can hang. */\r
+#define SYSCTL_NODE(parent, nbr, name, access, handler, descr) \\r
+       extern struct linker_set sysctl_##parent##_##name; \\r
+       SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|access, \\r
+               (void*)&sysctl_##parent##_##name, 0, handler, "N", descr); \\r
+       DATA_SET(sysctl_##parent##_##name, sysctl__##parent##_##name)\r
+#else\r
+#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr)\r
+#define SYSCTL_NODE(parent, nbr, name, access, handler, descr)\r
+#endif\r
+\r
+/* Oid for a string.  len can be 0 to indicate '\0' termination. */\r
+#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \\r
+       SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|access, \\r
+               arg, len, sysctl_handle_string, "A", descr)\r
+\r
+/* Oid for an int.  If ptr is NULL, val is returned. */\r
+#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \\r
+       SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \\r
+               ptr, val, sysctl_handle_int, "I", descr)\r
+\r
+/* Oid for a long.  The pointer must be non NULL. */\r
+#define SYSCTL_LONG(parent, nbr, name, access, ptr, descr) \\r
+       SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \\r
+               ptr, 0, sysctl_handle_long, "L", descr)\r
+\r
+/* Oid for an opaque object.  Specified by a pointer and a length. */\r
+#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \\r
+       SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|access, \\r
+               ptr, len, sysctl_handle_opaque, fmt, descr)\r
+\r
+/* Oid for a struct.  Specified by a pointer and a type. */\r
+#define SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr) \\r
+       SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|access, \\r
+               ptr, sizeof(struct type), sysctl_handle_opaque, \\r
+               "S," #type, descr)\r
+\r
+/* Oid for a procedure.  Specified by a pointer and an arg. */\r
+#define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \\r
+       SYSCTL_OID(parent, nbr, name, access, \\r
+               ptr, arg, handler, fmt, descr)\r
+#endif /* KERNEL */\r
+\r
+/*\r
+ * Top-level identifiers\r
+ */\r
+#define        CTL_UNSPEC      0               /* unused */\r
+#define        CTL_KERN        1               /* "high kernel": proc, limits */\r
+#define        CTL_VM          2               /* virtual memory */\r
+#define        CTL_VFS         3               /* file system, mount type is next */\r
+#define        CTL_NET         4               /* network, see socket.h */\r
+#define        CTL_DEBUG       5               /* debugging parameters */\r
+#define        CTL_HW          6               /* generic cpu/io */\r
+#define        CTL_MACHDEP     7               /* machine dependent */\r
+#define        CTL_USER        8               /* user-level */\r
+#define        CTL_P1003_1B    9               /* POSIX 1003.1B */\r
+#define        CTL_MAXID       10              /* number of valid top-level ids */\r
+\r
+#define CTL_NAMES { \\r
+       { 0, 0 }, \\r
+       { "kern", CTLTYPE_NODE }, \\r
+       { "vm", CTLTYPE_NODE }, \\r
+       { "vfs", CTLTYPE_NODE }, \\r
+       { "net", CTLTYPE_NODE }, \\r
+       { "debug", CTLTYPE_NODE }, \\r
+       { "hw", CTLTYPE_NODE }, \\r
+       { "machdep", CTLTYPE_NODE }, \\r
+       { "user", CTLTYPE_NODE }, \\r
+       { "p1003_1b", CTLTYPE_NODE }, \\r
+}\r
+\r
+/*\r
+ * CTL_KERN identifiers\r
+ */\r
+#define        KERN_OSTYPE              1      /* string: system version */\r
+#define        KERN_OSRELEASE           2      /* string: system release */\r
+#define        KERN_OSREV               3      /* int: system revision */\r
+#define        KERN_VERSION             4      /* string: compile time info */\r
+#define        KERN_MAXVNODES           5      /* int: max vnodes */\r
+#define        KERN_MAXPROC             6      /* int: max processes */\r
+#define        KERN_MAXFILES            7      /* int: max open files */\r
+#define        KERN_ARGMAX              8      /* int: max arguments to exec */\r
+#define        KERN_SECURELVL           9      /* int: system security level */\r
+#define        KERN_HOSTNAME           10      /* string: hostname */\r
+#define        KERN_HOSTID             11      /* int: host identifier */\r
+#define        KERN_CLOCKRATE          12      /* struct: struct clockrate */\r
+#define        KERN_VNODE              13      /* struct: vnode structures */\r
+#define        KERN_PROC               14      /* struct: process entries */\r
+#define        KERN_FILE               15      /* struct: file entries */\r
+#define        KERN_PROF               16      /* node: kernel profiling info */\r
+#define        KERN_POSIX1             17      /* int: POSIX.1 version */\r
+#define        KERN_NGROUPS            18      /* int: # of supplemental group ids */\r
+#define        KERN_JOB_CONTROL        19      /* int: is job control available */\r
+#define        KERN_SAVED_IDS          20      /* int: saved set-user/group-ID */\r
+#define        KERN_BOOTTIME           21      /* struct: time kernel was booted */\r
+#define KERN_NISDOMAINNAME     22      /* string: YP domain name */\r
+#define KERN_UPDATEINTERVAL    23      /* int: update process sleep time */\r
+#define KERN_OSRELDATE         24      /* int: OS release date */\r
+#define KERN_NTP_PLL           25      /* node: NTP PLL control */\r
+#define        KERN_BOOTFILE           26      /* string: name of booted kernel */\r
+#define        KERN_MAXFILESPERPROC    27      /* int: max open files per proc */\r
+#define        KERN_MAXPROCPERUID      28      /* int: max processes per uid */\r
+#define KERN_DUMPDEV           29      /* dev_t: device to dump on */\r
+#define        KERN_IPC                30      /* node: anything related to IPC */\r
+#define        KERN_DUMMY              31      /* unused */\r
+#define        KERN_PS_STRINGS         32      /* int: address of PS_STRINGS */\r
+#define        KERN_USRSTACK           33      /* int: address of USRSTACK */\r
+#define        KERN_LOGSIGEXIT         34      /* int: do we log sigexit procs? */\r
+#define KERN_MAXID             35      /* number of valid kern ids */\r
+\r
+#define CTL_KERN_NAMES { \\r
+       { 0, 0 }, \\r
+       { "ostype", CTLTYPE_STRING }, \\r
+       { "osrelease", CTLTYPE_STRING }, \\r
+       { "osrevision", CTLTYPE_INT }, \\r
+       { "version", CTLTYPE_STRING }, \\r
+       { "maxvnodes", CTLTYPE_INT }, \\r
+       { "maxproc", CTLTYPE_INT }, \\r
+       { "maxfiles", CTLTYPE_INT }, \\r
+       { "argmax", CTLTYPE_INT }, \\r
+       { "securelevel", CTLTYPE_INT }, \\r
+       { "hostname", CTLTYPE_STRING }, \\r
+       { "hostid", CTLTYPE_INT }, \\r
+       { "clockrate", CTLTYPE_STRUCT }, \\r
+       { "vnode", CTLTYPE_STRUCT }, \\r
+       { "proc", CTLTYPE_STRUCT }, \\r
+       { "file", CTLTYPE_STRUCT }, \\r
+       { "profiling", CTLTYPE_NODE }, \\r
+       { "posix1version", CTLTYPE_INT }, \\r
+       { "ngroups", CTLTYPE_INT }, \\r
+       { "job_control", CTLTYPE_INT }, \\r
+       { "saved_ids", CTLTYPE_INT }, \\r
+       { "boottime", CTLTYPE_STRUCT }, \\r
+       { "nisdomainname", CTLTYPE_STRING }, \\r
+       { "update", CTLTYPE_INT }, \\r
+       { "osreldate", CTLTYPE_INT }, \\r
+        { "ntp_pll", CTLTYPE_NODE }, \\r
+       { "bootfile", CTLTYPE_STRING }, \\r
+       { "maxfilesperproc", CTLTYPE_INT }, \\r
+       { "maxprocperuid", CTLTYPE_INT }, \\r
+       { "dumpdev", CTLTYPE_STRUCT }, /* we lie; don't print as int */ \\r
+       { "ipc", CTLTYPE_NODE }, \\r
+       { "dummy", CTLTYPE_INT }, \\r
+       { "ps_strings", CTLTYPE_INT }, \\r
+       { "usrstack", CTLTYPE_INT }, \\r
+       { "logsigexit", CTLTYPE_INT }, \\r
+}\r
+\r
+/*\r
+ * CTL_VFS identifiers\r
+ */\r
+#define CTL_VFS_NAMES { \\r
+       { "vfsconf", CTLTYPE_STRUCT }, \\r
+}\r
+\r
+/*\r
+ * KERN_PROC subtypes\r
+ */\r
+#define KERN_PROC_ALL          0       /* everything */\r
+#define        KERN_PROC_PID           1       /* by process id */\r
+#define        KERN_PROC_PGRP          2       /* by process group id */\r
+#define        KERN_PROC_SESSION       3       /* by session of pid */\r
+#define        KERN_PROC_TTY           4       /* by controlling tty */\r
+#define        KERN_PROC_UID           5       /* by effective uid */\r
+#define        KERN_PROC_RUID          6       /* by real uid */\r
+\r
+/*\r
+ * KERN_IPC identifiers\r
+ */\r
+#define KIPC_MAXSOCKBUF                1       /* int: max size of a socket buffer */\r
+#define        KIPC_SOCKBUF_WASTE      2       /* int: wastage factor in sockbuf */\r
+#define        KIPC_SOMAXCONN          3       /* int: max length of connection q */\r
+#define        KIPC_MAX_LINKHDR        4       /* int: max length of link header */\r
+#define        KIPC_MAX_PROTOHDR       5       /* int: max length of network header */\r
+#define        KIPC_MAX_HDR            6       /* int: max total length of headers */\r
+#define        KIPC_MAX_DATALEN        7       /* int: max length of data? */\r
+#define        KIPC_MBSTAT             8       /* struct: mbuf usage statistics */\r
+#define        KIPC_NMBCLUSTERS        9       /* int: maximum mbuf clusters */\r
+\r
+/*\r
+ * CTL_HW identifiers\r
+ */\r
+#define        HW_MACHINE       1              /* string: machine class */\r
+#define        HW_MODEL         2              /* string: specific machine model */\r
+#define        HW_NCPU          3              /* int: number of cpus */\r
+#define        HW_BYTEORDER     4              /* int: machine byte order */\r
+#define        HW_PHYSMEM       5              /* int: total memory */\r
+#define        HW_USERMEM       6              /* int: non-kernel memory */\r
+#define        HW_PAGESIZE      7              /* int: software page size */\r
+#define        HW_DISKNAMES     8              /* strings: disk drive names */\r
+#define        HW_DISKSTATS     9              /* struct: diskstats[] */\r
+#define HW_FLOATINGPT  10              /* int: has HW floating point? */\r
+#define HW_MACHINE_ARCH        11              /* string: machine architecture */\r
+#define        HW_MAXID        12              /* number of valid hw ids */\r
+\r
+#define CTL_HW_NAMES { \\r
+       { 0, 0 }, \\r
+       { "machine", CTLTYPE_STRING }, \\r
+       { "model", CTLTYPE_STRING }, \\r
+       { "ncpu", CTLTYPE_INT }, \\r
+       { "byteorder", CTLTYPE_INT }, \\r
+       { "physmem", CTLTYPE_INT }, \\r
+       { "usermem", CTLTYPE_INT }, \\r
+       { "pagesize", CTLTYPE_INT }, \\r
+       { "disknames", CTLTYPE_STRUCT }, \\r
+       { "diskstats", CTLTYPE_STRUCT }, \\r
+       { "floatingpoint", CTLTYPE_INT }, \\r
+}\r
+\r
+/*\r
+ * CTL_USER definitions\r
+ */\r
+#define        USER_CS_PATH             1      /* string: _CS_PATH */\r
+#define        USER_BC_BASE_MAX         2      /* int: BC_BASE_MAX */\r
+#define        USER_BC_DIM_MAX          3      /* int: BC_DIM_MAX */\r
+#define        USER_BC_SCALE_MAX        4      /* int: BC_SCALE_MAX */\r
+#define        USER_BC_STRING_MAX       5      /* int: BC_STRING_MAX */\r
+#define        USER_COLL_WEIGHTS_MAX    6      /* int: COLL_WEIGHTS_MAX */\r
+#define        USER_EXPR_NEST_MAX       7      /* int: EXPR_NEST_MAX */\r
+#define        USER_LINE_MAX            8      /* int: LINE_MAX */\r
+#define        USER_RE_DUP_MAX          9      /* int: RE_DUP_MAX */\r
+#define        USER_POSIX2_VERSION     10      /* int: POSIX2_VERSION */\r
+#define        USER_POSIX2_C_BIND      11      /* int: POSIX2_C_BIND */\r
+#define        USER_POSIX2_C_DEV       12      /* int: POSIX2_C_DEV */\r
+#define        USER_POSIX2_CHAR_TERM   13      /* int: POSIX2_CHAR_TERM */\r
+#define        USER_POSIX2_FORT_DEV    14      /* int: POSIX2_FORT_DEV */\r
+#define        USER_POSIX2_FORT_RUN    15      /* int: POSIX2_FORT_RUN */\r
+#define        USER_POSIX2_LOCALEDEF   16      /* int: POSIX2_LOCALEDEF */\r
+#define        USER_POSIX2_SW_DEV      17      /* int: POSIX2_SW_DEV */\r
+#define        USER_POSIX2_UPE         18      /* int: POSIX2_UPE */\r
+#define        USER_STREAM_MAX         19      /* int: POSIX2_STREAM_MAX */\r
+#define        USER_TZNAME_MAX         20      /* int: POSIX2_TZNAME_MAX */\r
+#define        USER_MAXID              21      /* number of valid user ids */\r
+\r
+#define        CTL_USER_NAMES { \\r
+       { 0, 0 }, \\r
+       { "cs_path", CTLTYPE_STRING }, \\r
+       { "bc_base_max", CTLTYPE_INT }, \\r
+       { "bc_dim_max", CTLTYPE_INT }, \\r
+       { "bc_scale_max", CTLTYPE_INT }, \\r
+       { "bc_string_max", CTLTYPE_INT }, \\r
+       { "coll_weights_max", CTLTYPE_INT }, \\r
+       { "expr_nest_max", CTLTYPE_INT }, \\r
+       { "line_max", CTLTYPE_INT }, \\r
+       { "re_dup_max", CTLTYPE_INT }, \\r
+       { "posix2_version", CTLTYPE_INT }, \\r
+       { "posix2_c_bind", CTLTYPE_INT }, \\r
+       { "posix2_c_dev", CTLTYPE_INT }, \\r
+       { "posix2_char_term", CTLTYPE_INT }, \\r
+       { "posix2_fort_dev", CTLTYPE_INT }, \\r
+       { "posix2_fort_run", CTLTYPE_INT }, \\r
+       { "posix2_localedef", CTLTYPE_INT }, \\r
+       { "posix2_sw_dev", CTLTYPE_INT }, \\r
+       { "posix2_upe", CTLTYPE_INT }, \\r
+       { "stream_max", CTLTYPE_INT }, \\r
+       { "tzname_max", CTLTYPE_INT }, \\r
+}\r
+\r
+#define CTL_P1003_1B_ASYNCHRONOUS_IO           1       /* boolean */\r
+#define CTL_P1003_1B_MAPPED_FILES              2       /* boolean */\r
+#define CTL_P1003_1B_MEMLOCK                   3       /* boolean */\r
+#define CTL_P1003_1B_MEMLOCK_RANGE             4       /* boolean */\r
+#define CTL_P1003_1B_MEMORY_PROTECTION         5       /* boolean */\r
+#define CTL_P1003_1B_MESSAGE_PASSING           6       /* boolean */\r
+#define CTL_P1003_1B_PRIORITIZED_IO            7       /* boolean */\r
+#define CTL_P1003_1B_PRIORITY_SCHEDULING       8       /* boolean */\r
+#define CTL_P1003_1B_REALTIME_SIGNALS          9       /* boolean */\r
+#define CTL_P1003_1B_SEMAPHORES                        10      /* boolean */\r
+#define CTL_P1003_1B_FSYNC                     11      /* boolean */\r
+#define CTL_P1003_1B_SHARED_MEMORY_OBJECTS     12      /* boolean */\r
+#define CTL_P1003_1B_SYNCHRONIZED_IO           13      /* boolean */\r
+#define CTL_P1003_1B_TIMERS                    14      /* boolean */\r
+#define CTL_P1003_1B_AIO_LISTIO_MAX            15      /* int */\r
+#define CTL_P1003_1B_AIO_MAX                   16      /* int */\r
+#define CTL_P1003_1B_AIO_PRIO_DELTA_MAX                17      /* int */\r
+#define CTL_P1003_1B_DELAYTIMER_MAX            18      /* int */\r
+#define CTL_P1003_1B_MQ_OPEN_MAX               19      /* int */\r
+#define CTL_P1003_1B_PAGESIZE                  20      /* int */\r
+#define CTL_P1003_1B_RTSIG_MAX                 21      /* int */\r
+#define CTL_P1003_1B_SEM_NSEMS_MAX             22      /* int */\r
+#define CTL_P1003_1B_SEM_VALUE_MAX             23      /* int */\r
+#define CTL_P1003_1B_SIGQUEUE_MAX              24      /* int */\r
+#define CTL_P1003_1B_TIMER_MAX                 25      /* int */\r
+\r
+#define CTL_P1003_1B_MAXID             26\r
+\r
+#define        CTL_P1003_1B_NAMES { \\r
+       { 0, 0 }, \\r
+       { "asynchronous_io", CTLTYPE_INT }, \\r
+       { "mapped_files", CTLTYPE_INT }, \\r
+       { "memlock", CTLTYPE_INT }, \\r
+       { "memlock_range", CTLTYPE_INT }, \\r
+       { "memory_protection", CTLTYPE_INT }, \\r
+       { "message_passing", CTLTYPE_INT }, \\r
+       { "prioritized_io", CTLTYPE_INT }, \\r
+       { "priority_scheduling", CTLTYPE_INT }, \\r
+       { "realtime_signals", CTLTYPE_INT }, \\r
+       { "semaphores", CTLTYPE_INT }, \\r
+       { "fsync", CTLTYPE_INT }, \\r
+       { "shared_memory_objects", CTLTYPE_INT }, \\r
+       { "synchronized_io", CTLTYPE_INT }, \\r
+       { "timers", CTLTYPE_INT }, \\r
+       { "aio_listio_max", CTLTYPE_INT }, \\r
+       { "aio_max", CTLTYPE_INT }, \\r
+       { "aio_prio_delta_max", CTLTYPE_INT }, \\r
+       { "delaytimer_max", CTLTYPE_INT }, \\r
+       { "mq_open_max", CTLTYPE_INT }, \\r
+       { "pagesize", CTLTYPE_INT }, \\r
+       { "rtsig_max", CTLTYPE_INT }, \\r
+       { "nsems_max", CTLTYPE_INT }, \\r
+       { "sem_value_max", CTLTYPE_INT }, \\r
+       { "sigqueue_max", CTLTYPE_INT }, \\r
+       { "timer_max", CTLTYPE_INT }, \\r
+}\r
+\r
+#ifdef KERNEL\r
+\r
+extern char    machine[];\r
+extern char    osrelease[];\r
+extern char    ostype[];\r
+\r
+int    kernel_sysctl(struct proc *p, int *name, u_int namelen, void *old,\r
+                     size_t *oldlenp, void *new, size_t newlen,\r
+                     size_t *retval);\r
+void   sysctl_order_all(void);\r
+int    userland_sysctl(struct proc *p, int *name, u_int namelen, void *old,\r
+                       size_t *oldlenp, int inkernel, void *new, size_t newlen,\r
+                       size_t *retval);\r
+\r
+#else  /* !KERNEL */\r
+#include <sys/EfiCdefs.h>\r
+\r
+__BEGIN_DECLS\r
+int    sysctl __P((int *, u_int, void *, size_t *, void *, size_t));\r
+int    sysctlbyname __P((const char *, void *, size_t *, void *, size_t));\r
+__END_DECLS\r
+#endif /* KERNEL */\r
+\r
+#endif /* !_SYS_SYSCTL_H_ */\r
index 80b18c3917632b4cb0c48f99aff07d7d651531ff..d308387f2a81273c0bfb4a63d388506d2c0d3091 100644 (file)
@@ -37,7 +37,7 @@
 #include <sys/featuretest.h>\r
 \r
 #define ARG_MAX    (2 * 1024) /* max bytes for an exec function */\r
-#define ARGC_MAX    (ARG_MAX / 2)   /* Maximum value for argc */\r
+#define ARGC_MAX       (64)   /* Maximum value for argc */\r
 \r
 #ifndef CHILD_MAX\r
   #define CHILD_MAX     128 /* max simultaneous processes */\r
index 4b1731720057dfdaf8e0866241ce2adbcf020d8e..b8957f4c4171d0b21fd27b5949447759ec91eeeb 100644 (file)
@@ -71,6 +71,7 @@ struct timespec {
   (ts)->tv_sec = (tv)->tv_sec;          \\r
   (ts)->tv_nsec = (tv)->tv_usec * 1000;       \\r
 } while (/*CONSTCOND*/0)\r
+\r
 #define TIMESPEC_TO_TIMEVAL(tv, ts) do {        \\r
   (tv)->tv_sec = (ts)->tv_sec;          \\r
   (tv)->tv_usec = (ts)->tv_nsec / 1000;       \\r
@@ -79,10 +80,12 @@ struct timespec {
 /* Operations on timevals. */\r
 #define timerclear(tvp)   (tvp)->tv_sec = (tvp)->tv_usec = 0\r
 #define timerisset(tvp)   ((tvp)->tv_sec || (tvp)->tv_usec)\r
+\r
 #define timercmp(tvp, uvp, cmp)           \\r
   (((tvp)->tv_sec == (uvp)->tv_sec) ?       \\r
       ((tvp)->tv_usec cmp (uvp)->tv_usec) :     \\r
       ((tvp)->tv_sec cmp (uvp)->tv_sec))\r
+\r
 #define timeradd(tvp, uvp, vvp)           \\r
   do {                \\r
     (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;    \\r
@@ -92,6 +95,7 @@ struct timespec {
       (vvp)->tv_usec -= 1000000;      \\r
     }             \\r
   } while (/* CONSTCOND */ 0)\r
+\r
 #define timersub(tvp, uvp, vvp)           \\r
   do {                \\r
     (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;    \\r
@@ -105,10 +109,12 @@ struct timespec {
 /* Operations on timespecs. */\r
 #define timespecclear(tsp)    (tsp)->tv_sec = (tsp)->tv_nsec = 0\r
 #define timespecisset(tsp)    ((tsp)->tv_sec || (tsp)->tv_nsec)\r
+\r
 #define timespeccmp(tsp, usp, cmp)          \\r
   (((tsp)->tv_sec == (usp)->tv_sec) ?       \\r
       ((tsp)->tv_nsec cmp (usp)->tv_nsec) :     \\r
       ((tsp)->tv_sec cmp (usp)->tv_sec))\r
+\r
 #define timespecadd(tsp, usp, vsp)          \\r
   do {                \\r
     (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec;    \\r
@@ -118,6 +124,7 @@ struct timespec {
       (vsp)->tv_nsec -= 1000000000L;      \\r
     }             \\r
   } while (/* CONSTCOND */ 0)\r
+\r
 #define timespecsub(tsp, usp, vsp)          \\r
   do {                \\r
     (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec;    \\r
@@ -182,5 +189,8 @@ __END_DECLS
 \r
 /* BSD compatibility functions */\r
 int gettimeofday (struct timeval *tp, void *ignore);\r
+/* POSIX compatibility functions */\r
+int getitimer (int which, struct itimerval *value);\r
+int setitimer (int which, const struct itimerval *value, struct itimerval *ovalue);\r
 \r
 #endif /* !_SYS_TIME_H_ */\r
index 0e7158c7c85d6fa065faf28a6ba4d1b42f213447..a63d88df55ea8756d199a03b70ce1e301ad32428 100644 (file)
@@ -37,7 +37,7 @@
 #include <sys/featuretest.h>\r
 \r
 /* compile-time symbolic constants */\r
-#define _POSIX_JOB_CONTROL  /* implementation supports job control */\r
+//#define _POSIX_JOB_CONTROL  /* implementation supports job control */\r
 \r
 /*\r
  * According to POSIX 1003.1:\r
 \r
 /* execution-time symbolic constants */\r
         /* chown requires appropriate privileges */\r
-#define _POSIX_CHOWN_RESTRICTED 1\r
-        /* clock selection */\r
-#define _POSIX_CLOCK_SELECTION  -1\r
-        /* too-long path components generate errors */\r
-#define _POSIX_NO_TRUNC   1\r
-        /* may disable terminal special characters */\r
-#define _POSIX_VDISABLE   ((unsigned char)'\377')\r
-        /* file synchronization is available */\r
-#define _POSIX_FSYNC    1\r
-        /* synchronized I/O is available */\r
-#define _POSIX_SYNCHRONIZED_IO  1\r
-        /* memory mapped files */\r
-#define _POSIX_MAPPED_FILES 1\r
-        /* memory locking of whole address space */\r
-#define _POSIX_MEMLOCK    1\r
-        /* memory locking address ranges */\r
-#define _POSIX_MEMLOCK_RANGE  1\r
-        /* memory access protections */\r
-#define _POSIX_MEMORY_PROTECTION 1\r
-        /* monotonic clock */\r
-#define _POSIX_MONOTONIC_CLOCK  200112L\r
-        /* threads */\r
-#define _POSIX_THREADS    200112L\r
-        /* semaphores */\r
-#define _POSIX_SEMAPHORES 0\r
-        /* barriers */\r
-#define _POSIX_BARRIERS   200112L\r
+//#define _POSIX_CHOWN_RESTRICTED 1\r
+//        /* clock selection */\r
+//#define _POSIX_CLOCK_SELECTION  -1\r
+//        /* too-long path components generate errors */\r
+//#define _POSIX_NO_TRUNC   1\r
+//        /* may disable terminal special characters */\r
+//#define _POSIX_VDISABLE   ((unsigned char)'\377')\r
+//        /* file synchronization is available */\r
+//#define _POSIX_FSYNC    1\r
+//        /* synchronized I/O is available */\r
+//#define _POSIX_SYNCHRONIZED_IO  1\r
+//        /* memory mapped files */\r
+//#define _POSIX_MAPPED_FILES 1\r
+//        /* memory locking of whole address space */\r
+//#define _POSIX_MEMLOCK    1\r
+//        /* memory locking address ranges */\r
+//#define _POSIX_MEMLOCK_RANGE  1\r
+//        /* memory access protections */\r
+//#define _POSIX_MEMORY_PROTECTION 1\r
+//        /* monotonic clock */\r
+//#define _POSIX_MONOTONIC_CLOCK  200112L\r
+//        /* threads */\r
+//#define _POSIX_THREADS    200112L\r
+//        /* semaphores */\r
+//#define _POSIX_SEMAPHORES 0\r
+//        /* barriers */\r
+//#define _POSIX_BARRIERS   200112L\r
         /* timers */\r
 #define _POSIX_TIMERS   200112L\r
         /* spin locks */\r
-#define _POSIX_SPIN_LOCKS 200112L\r
-        /* read/write locks */\r
-#define _POSIX_READER_WRITER_LOCKS  200112L\r
-        /* XPG4.2 shared memory */\r
-#define _XOPEN_SHM    0\r
+//#define _POSIX_SPIN_LOCKS 200112L\r
+//        /* read/write locks */\r
+//#define _POSIX_READER_WRITER_LOCKS  200112L\r
+//        /* XPG4.2 shared memory */\r
+//#define _XOPEN_SHM    0\r
 \r
-#if defined(_NETBSD_SOURCE)\r
 /* whence values for lseek(2); renamed by POSIX 1003.1 */\r
 #define L_SET   SEEK_SET\r
 #define L_INCR    SEEK_CUR\r
 #define FDATASYNC 0x0010  /* sync data and minimal metadata */\r
 #define FFILESYNC 0x0020  /* sync data and metadata */\r
 #define FDISKSYNC 0x0040  /* flush disk caches after sync */\r
-#endif\r
 \r
 /* configurable pathname variables; use as argument to pathconf(3) */\r
 #define _PC_LINK_MAX     1\r
diff --git a/StdLib/Include/sys/wait.h b/StdLib/Include/sys/wait.h
new file mode 100644 (file)
index 0000000..64200aa
--- /dev/null
@@ -0,0 +1,170 @@
+/*  $NetBSD: wait.h,v 1.24 2005/12/11 12:25:21 christos Exp $ */\r
+\r
+/*\r
+ * Copyright (c) 1982, 1986, 1989, 1993, 1994\r
+ *  The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *  @(#)wait.h  8.2 (Berkeley) 7/10/94\r
+ */\r
+#ifndef _SYS_WAIT_H_\r
+#define _SYS_WAIT_H_\r
+\r
+#include <sys/featuretest.h>\r
+#include <sys/types.h>\r
+\r
+/*\r
+ * This file holds definitions relevent to the wait4 system call\r
+ * and the alternate interfaces that use it (wait, wait3, waitpid).\r
+ */\r
+\r
+/*\r
+ * Macros to test the exit status returned by wait\r
+ * and extract the relevant values.\r
+ */\r
+#define _W_INT(w) (*(int *)(void *)&(w))  /* convert union wait to int */\r
+\r
+#define _WSTATUS(x) (_W_INT(x) & 0177)\r
+#define _WSTOPPED 0177    /* _WSTATUS if process is stopped */\r
+#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)\r
+#define WSTOPSIG(x) ((int)(((unsigned int)_W_INT(x)) >> 8) & 0xff)\r
+#define WIFSIGNALED(x)  (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)\r
+#define WTERMSIG(x) (_WSTATUS(x))\r
+#define WIFEXITED(x)  (_WSTATUS(x) == 0)\r
+#define WEXITSTATUS(x)  ((int)(((unsigned int)_W_INT(x)) >> 8) & 0xff)\r
+#define WCOREFLAG 0200\r
+#define WCOREDUMP(x)  (_W_INT(x) & WCOREFLAG)\r
+\r
+#define W_EXITCODE(ret, sig)  ((ret) << 8 | (sig))\r
+#define W_STOPCODE(sig)   ((sig) << 8 | _WSTOPPED)\r
+\r
+/*\r
+ * Option bits for the third argument of wait4.  WNOHANG causes the\r
+ * wait to not hang if there are no stopped or terminated processes, rather\r
+ * returning an error indication in this case (pid==0).  WUNTRACED\r
+ * indicates that the caller should receive status about untraced children\r
+ * which stop due to signals.  If children are stopped and a wait without\r
+ * this option is done, it is as though they were still running... nothing\r
+ * about them is returned.\r
+ */\r
+#define WNOHANG   0x00000001  /* don't hang in wait */\r
+#define WUNTRACED 0x00000002  /* tell about stopped,\r
+             untraced children */\r
+#if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)\r
+#define WALTSIG   0x00000004  /* wait for processes that exit\r
+             with an alternate signal (i.e.\r
+             not SIGCHLD) */\r
+#define WALLSIG   0x00000008  /* wait for processes that exit\r
+             with any signal, i.e. SIGCHLD\r
+             and alternates */\r
+\r
+/*\r
+ * These are the Linux names of some of the above flags, for compatibility\r
+ * with Linux's clone(2) API.\r
+ */\r
+#define __WCLONE  WALTSIG\r
+#define __WALL    WALLSIG\r
+\r
+/*\r
+ * These bits are used in order to support SVR4 (etc) functionality\r
+ * without replicating sys_wait4 5 times.\r
+ */\r
+#define WNOWAIT   0x00010000  /* Don't mark child 'P_WAITED' */\r
+#define WNOZOMBIE 0x00020000  /* Ignore zombies */\r
+#endif /* _XOPEN_SOURCE || _NETBSD_SOURCE */\r
+\r
+/* POSIX extensions and 4.2/4.3 compatibility: */\r
+\r
+/*\r
+ * Tokens for special values of the "pid" parameter to wait4.\r
+ */\r
+#define WAIT_ANY  (-1)  /* any process */\r
+#define WAIT_MYPGRP 0 /* any process in my process group */\r
+\r
+/*\r
+ * Deprecated:\r
+ * Structure of the information in the status word returned by wait4.\r
+ * If w_stopval==WSTOPPED, then the second structure describes\r
+ * the information returned, else the first.\r
+ */\r
+union wait {\r
+  int w_status;   /* used in syscall */\r
+  /*\r
+   * Terminated process status.\r
+   */\r
+  struct {\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+    unsigned int  w_Termsig:7,  /* termination signal */\r
+        w_Coredump:1, /* core dump indicator */\r
+        w_Retcode:8,  /* exit code if w_termsig==0 */\r
+        w_Filler:16;  /* upper bits filler */\r
+#endif\r
+#if BYTE_ORDER == BIG_ENDIAN\r
+    unsigned int  w_Filler:16,  /* upper bits filler */\r
+        w_Retcode:8,  /* exit code if w_termsig==0 */\r
+        w_Coredump:1, /* core dump indicator */\r
+        w_Termsig:7;  /* termination signal */\r
+#endif\r
+  } w_T;\r
+  /*\r
+   * Stopped process status.  Returned\r
+   * only for traced children unless requested\r
+   * with the WUNTRACED option bit.\r
+   */\r
+  struct {\r
+#if BYTE_ORDER == LITTLE_ENDIAN\r
+    unsigned int  w_Stopval:8,  /* == W_STOPPED if stopped */\r
+        w_Stopsig:8,  /* signal that stopped us */\r
+        w_Filler:16;  /* upper bits filler */\r
+#endif\r
+#if BYTE_ORDER == BIG_ENDIAN\r
+    unsigned int  w_Filler:16,  /* upper bits filler */\r
+        w_Stopsig:8,  /* signal that stopped us */\r
+        w_Stopval:8;  /* == W_STOPPED if stopped */\r
+#endif\r
+  } w_S;\r
+};\r
+#define w_termsig w_T.w_Termsig\r
+#define w_coredump  w_T.w_Coredump\r
+#define w_retcode w_T.w_Retcode\r
+#define w_stopval w_S.w_Stopval\r
+#define w_stopsig w_S.w_Stopsig\r
+\r
+#define WSTOPPED  _WSTOPPED\r
+\r
+__BEGIN_DECLS\r
+pid_t wait(int *);\r
+\r
+#if 0   /* Normally declared here but not implemented for UEFI. */\r
+struct rusage;  /* forward declaration */\r
+\r
+pid_t waitpid(pid_t, int *, int);\r
+pid_t wait3(int *, int, struct rusage *);\r
+pid_t wait4(pid_t, int *, int, struct rusage *);\r
+#endif\r
+__END_DECLS\r
+\r
+#endif /* !_SYS_WAIT_H_ */\r
diff --git a/StdLib/Include/sysexits.h b/StdLib/Include/sysexits.h
new file mode 100644 (file)
index 0000000..e18348d
--- /dev/null
@@ -0,0 +1,122 @@
+/** @file contains exit code definitions for exiting systems applications.\r
+\r
+  These exit codes are an extension beyond the two values specified by\r
+  ISO/IEC 9899:199409 and defined in <stdlib.h>.\r
+\r
+ * Copyright (c) 1987, 1993\r
+ *  The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *  This product includes software developed by the University of\r
+ *  California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *  @(#)sysexits.h  8.1 (Berkeley) 6/2/93\r
+ */\r
+\r
+#ifndef _SYSEXITS_H_\r
+#define _SYSEXITS_H_\r
+\r
+/*\r
+ *  SYSEXITS.H -- Exit status codes for system programs.\r
+ *\r
+ *  This include file attempts to categorize possible error\r
+ *  exit statuses for system programs, notably delivermail\r
+ *  and the Berkeley network.\r
+ *\r
+ *  Error numbers begin at EX__BASE to reduce the possibility of\r
+ *  clashing with other exit statuses that random programs may\r
+ *  already return.  The meaning of the codes is approximately\r
+ *  as follows:\r
+ *\r
+ *  EX_USAGE -- The command was used incorrectly, e.g., with\r
+ *    the wrong number of arguments, a bad flag, a bad\r
+ *    syntax in a parameter, or whatever.\r
+ *  EX_DATAERR -- The input data was incorrect in some way.\r
+ *    This should only be used for user's data & not\r
+ *    system files.\r
+ *  EX_NOINPUT -- An input file (not a system file) did not\r
+ *    exist or was not readable.  This could also include\r
+ *    errors like "No message" to a mailer (if it cared\r
+ *    to catch it).\r
+ *  EX_NOUSER -- The user specified did not exist.  This might\r
+ *    be used for mail addresses or remote logins.\r
+ *  EX_NOHOST -- The host specified did not exist.  This is used\r
+ *    in mail addresses or network requests.\r
+ *  EX_UNAVAILABLE -- A service is unavailable.  This can occur\r
+ *    if a support program or file does not exist.  This\r
+ *    can also be used as a catchall message when something\r
+ *    you wanted to do doesn't work, but you don't know\r
+ *    why.\r
+ *  EX_SOFTWARE -- An internal software error has been detected.\r
+ *    This should be limited to non-operating system related\r
+ *    errors as possible.\r
+ *  EX_OSERR -- An operating system error has been detected.\r
+ *    This is intended to be used for such things as "cannot\r
+ *    fork", "cannot create pipe", or the like.  It includes\r
+ *    things like getuid returning a user that does not\r
+ *    exist in the passwd file.\r
+ *  EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,\r
+ *    etc.) does not exist, cannot be opened, or has some\r
+ *    sort of error (e.g., syntax error).\r
+ *  EX_CANTCREAT -- A (user specified) output file cannot be\r
+ *    created.\r
+ *  EX_IOERR -- An error occurred while doing I/O on some file.\r
+ *  EX_TEMPFAIL -- temporary failure, indicating something that\r
+ *    is not really an error.  In sendmail, this means\r
+ *    that a mailer (e.g.) could not create a connection,\r
+ *    and the request should be reattempted later.\r
+ *  EX_PROTOCOL -- the remote system returned something that\r
+ *    was "not possible" during a protocol exchange.\r
+ *  EX_NOPERM -- You did not have sufficient permission to\r
+ *    perform the operation.  This is not intended for\r
+ *    file system problems, which should use NOINPUT or\r
+ *    CANTCREAT, but rather for higher level permissions.\r
+ */\r
+\r
+#define EX_OK   0 /* successful termination */\r
+\r
+#define EX__BASE  64  /* base value for error messages */\r
+\r
+#define EX_USAGE  64  /* command line usage error */\r
+#define EX_DATAERR  65  /* data format error */\r
+#define EX_NOINPUT  66  /* cannot open input */\r
+#define EX_NOUSER 67  /* addressee unknown */\r
+#define EX_NOHOST 68  /* host name unknown */\r
+#define EX_UNAVAILABLE  69  /* service unavailable */\r
+#define EX_SOFTWARE 70  /* internal software error */\r
+#define EX_OSERR  71  /* system error (e.g., can't fork) */\r
+#define EX_OSFILE 72  /* critical OS file missing */\r
+#define EX_CANTCREAT  73  /* can't create (user) output file */\r
+#define EX_IOERR  74  /* input/output error */\r
+#define EX_TEMPFAIL 75  /* temp failure; user is invited to retry */\r
+#define EX_PROTOCOL 76  /* remote error in protocol */\r
+#define EX_NOPERM 77  /* permission denied */\r
+#define EX_CONFIG 78  /* configuration error */\r
+\r
+#define EX__MAX 78  /* maximum listed value */\r
+\r
+#endif /* !_SYSEXITS_H_ */\r
index 8c7b8e14229fc52c09733ab2d2759a34558f152c..a0ebbb9881605a7498ab3dd5f9c30d18fc043c92 100644 (file)
 **/\r
 struct tm {\r
   int     tm_year;      // years since 1900\r
-  int     tm_mon;       // months since January \97 [0, 11]\r
-  int     tm_mday;      // day of the month \97 [1, 31]\r
-  int     tm_hour;      // hours since midnight \97 [0, 23]\r
-  int     tm_min;       // minutes after the hour \97 [0, 59]\r
-  int     tm_sec;       // seconds after the minute \97 [0, 60]\r
-  int     tm_wday;      // days since Sunday \97 [0, 6]\r
-  int     tm_yday;      // days since January 1 \97 [0, 365]\r
+  int     tm_mon;       // months since January  [0, 11]\r
+  int     tm_mday;      // day of the month  [1, 31]\r
+  int     tm_hour;      // hours since midnight  [0, 23]\r
+  int     tm_min;       // minutes after the hour  [0, 59]\r
+  int     tm_sec;       // seconds after the minute  [0, 60]\r
+  int     tm_wday;      // days since Sunday  [0, 6]\r
+  int     tm_yday;      // days since January 1  [0, 365]\r
   int     tm_isdst;     // Daylight Saving Time flag\r
   int     tm_zoneoff;   // EFI TimeZone offset, -1440 to 1440 or 2047\r
   int     tm_daylight;  // EFI Daylight flags\r
@@ -125,7 +125,7 @@ struct tm {
 \r
 /** The clock function determines the processor time used.\r
 \r
-    @return   The clock function returns the implementation\92s best\r
+    @return   The clock function returns the implementation's best\r
               approximation to the processor time used by the program since the\r
               beginning of an implementation-defined era related only to the\r
               program invocation.  To determine the time in seconds, the value\r
@@ -137,11 +137,11 @@ struct tm {
               On IA32 or X64 platforms, the value returned is the number of\r
               CPU TimeStamp Counter ticks since the appliation started.\r
 **/\r
-clock_t EFIAPI clock(void);\r
+clock_t  clock(void);\r
 \r
 /**\r
 **/\r
-double EFIAPI difftime(time_t time1, time_t time0);\r
+double difftime(time_t time1, time_t time0);\r
 \r
 /** The mktime function converts the broken-down time, expressed as local time,\r
     in the structure pointed to by timeptr into a calendar time value with the\r
@@ -159,19 +159,19 @@ double EFIAPI difftime(time_t time1, time_t time0);
               as a value of type time_t. If the calendar time cannot be\r
               represented, the function returns the value (time_t)(-1).\r
 **/\r
-time_t EFIAPI mktime(struct tm *timeptr);\r
+time_t mktime(struct tm *timeptr);\r
 \r
 /** The time function determines the current calendar time.\r
 \r
     The encoding of the value is unspecified.\r
 \r
-    @return   The time function returns the implementation\92s best approximation\r
+    @return   The time function returns the implementation's best approximation\r
               of the current calendar time. The value (time_t)(-1) is returned\r
               if the calendar time is not available. If timer is not a null\r
               pointer, the return value is also assigned to the object it\r
               points to.\r
 **/\r
-time_t EFIAPI time(time_t *timer);\r
+time_t time(time_t *timer);\r
 \r
 /* #################  Time Conversion Functions  ########################## */\r
 \r
@@ -181,7 +181,7 @@ time_t EFIAPI time(time_t *timer);
 \r
     @return   The asctime function returns a pointer to the string.\r
 **/\r
-char * EFIAPI asctime(const struct tm *timeptr);\r
+char * asctime(const struct tm *timeptr);\r
 \r
 /** The ctime function converts the calendar time pointed to by timer to local\r
     time in the form of a string. It is equivalent to asctime(localtime(timer))\r
@@ -189,7 +189,7 @@ char * EFIAPI asctime(const struct tm *timeptr);
     @return   The ctime function returns the pointer returned by the asctime\r
               function with that broken-down time as argument.\r
 **/\r
-char * EFIAPI ctime(const time_t *timer);\r
+char * ctime(const time_t *timer);\r
 \r
 /** The gmtime function converts the calendar time pointed to by timer into a\r
     brokendown time, expressed as UTC.\r
@@ -197,7 +197,13 @@ char * EFIAPI ctime(const time_t *timer);
     @return   The gmtime function returns a pointer to the broken-down time,\r
               or a null pointer if the specified time cannot be converted to UTC.\r
 **/\r
-struct tm  * EFIAPI gmtime(const time_t *timer);\r
+struct tm  * gmtime(const time_t *timer);\r
+\r
+/** The timegm function is the opposite of gmtime.\r
+\r
+    @return   The calendar time expressed as UTC.\r
+**/\r
+time_t timegm(struct tm*);\r
 \r
 /** The localtime function converts the calendar time pointed to by timer into\r
     a broken-down time, expressed as local time.\r
@@ -206,7 +212,7 @@ struct tm  * EFIAPI gmtime(const time_t *timer);
               or a null pointer if the specified time cannot be converted to\r
               local time.\r
 **/\r
-struct tm  * EFIAPI localtime(const time_t *timer);\r
+struct tm  * localtime(const time_t *timer);\r
 \r
 /** The strftime function places characters into the array pointed to by s as\r
     controlled by the string pointed to by format. The format shall be a\r
@@ -228,11 +234,11 @@ struct tm  * EFIAPI localtime(const time_t *timer);
     in the description. If any of the specified values is outside the normal\r
     range, the characters stored are unspecified.\r
 \r
-    %a is replaced by the locale\92s abbreviated weekday name. [tm_wday]\r
-    %A is replaced by the locale\92s full weekday name. [tm_wday]\r
-    %b is replaced by the locale\92s abbreviated month name. [tm_mon]\r
-    %B is replaced by the locale\92s full month name. [tm_mon]\r
-    %c is replaced by the locale\92s appropriate date and time representation.\r
+    %a is replaced by the locale's abbreviated weekday name. [tm_wday]\r
+    %A is replaced by the locale's full weekday name. [tm_wday]\r
+    %b is replaced by the locale's abbreviated month name. [tm_mon]\r
+    %B is replaced by the locale's full month name. [tm_mon]\r
+    %c is replaced by the locale's appropriate date and time representation.\r
     %C is replaced by the year divided by 100 and truncated to an integer,\r
        as a decimal number (00-99). [tm_year]\r
     %d is replaced by the day of the month as a decimal number (01-31). [tm_mday]\r
@@ -252,9 +258,9 @@ struct tm  * EFIAPI localtime(const time_t *timer);
     %m is replaced by the month as a decimal number (01-12). [tm_mon]\r
     %M is replaced by the minute as a decimal number (00-59). [tm_min]\r
     %n is replaced by a new-line character.\r
-    %p is replaced by the locale\92s equivalent of the AM/PM designations\r
+    %p is replaced by the locale's equivalent of the AM/PM designations\r
        associated with a 12-hour clock. [tm_hour]\r
-    %r is replaced by the locale\92s 12-hour clock time. [tm_hour, tm_min, tm_sec]\r
+    %r is replaced by the locale's 12-hour clock time. [tm_hour, tm_min, tm_sec]\r
     %R is equivalent to "%H:%M". [tm_hour, tm_min]\r
     %S is replaced by the second as a decimal number (00-60). [tm_sec]\r
     %t is replaced by a horizontal-tab character.\r
@@ -270,8 +276,8 @@ struct tm  * EFIAPI localtime(const time_t *timer);
        [tm_wday]\r
     %W is replaced by the week number of the year (the first Monday as the\r
        first day of week 1) as a decimal number (00-53). [tm_year, tm_wday, tm_yday]\r
-    %x is replaced by the locale\92s appropriate date representation.\r
-    %X is replaced by the locale\92s appropriate time representation.\r
+    %x is replaced by the locale's appropriate date representation.\r
+    %X is replaced by the locale's appropriate time representation.\r
     %y is replaced by the last 2 digits of the year as a decimal\r
        number (00-99). [tm_year]\r
     %Y is replaced by the year as a decimal number (e.g., 1997). [tm_year]\r
@@ -285,38 +291,38 @@ struct tm  * EFIAPI localtime(const time_t *timer);
     Some conversion specifiers can be modified by the inclusion of an E or O\r
     modifier character to indicate an alternative format or specification.\r
     If the alternative format or specification does not exist for the current\r
-    locale, the modifier is ignored. %Ec is replaced by the locale\92s\r
+    locale, the modifier is ignored. %Ec is replaced by the locale's\r
     alternative date and time representation.\r
 \r
-    %EC is replaced by the name of the base year (period) in the locale\92s\r
+    %EC is replaced by the name of the base year (period) in the locale's\r
         alternative representation.\r
-    %Ex is replaced by the locale\92s alternative date representation.\r
-    %EX is replaced by the locale\92s alternative time representation.\r
-    %Ey is replaced by the offset from %EC (year only) in the locale\92s\r
+    %Ex is replaced by the locale's alternative date representation.\r
+    %EX is replaced by the locale's alternative time representation.\r
+    %Ey is replaced by the offset from %EC (year only) in the locale's\r
         alternative representation.\r
-    %EY is replaced by the locale\92s full alternative year representation.\r
-    %Od is replaced by the day of the month, using the locale\92s alternative\r
+    %EY is replaced by the locale's full alternative year representation.\r
+    %Od is replaced by the day of the month, using the locale's alternative\r
         numeric symbols (filled as needed with leading zeros, or with leading\r
         spaces if there is no alternative symbol for zero).\r
-    %Oe is replaced by the day of the month, using the locale\92s alternative\r
+    %Oe is replaced by the day of the month, using the locale's alternative\r
         numeric symbols (filled as needed with leading spaces).\r
-    %OH is replaced by the hour (24-hour clock), using the locale\92s\r
+    %OH is replaced by the hour (24-hour clock), using the locale's\r
         alternative numeric symbols.\r
-    %OI is replaced by the hour (12-hour clock), using the locale\92s\r
+    %OI is replaced by the hour (12-hour clock), using the locale's\r
         alternative numeric symbols.\r
-    %Om is replaced by the month, using the locale\92s alternative numeric symbols.\r
-    %OM is replaced by the minutes, using the locale\92s alternative numeric symbols.\r
-    %OS is replaced by the seconds, using the locale\92s alternative numeric symbols.\r
-    %Ou is replaced by the ISO 8601 weekday as a number in the locale\92s\r
+    %Om is replaced by the month, using the locale's alternative numeric symbols.\r
+    %OM is replaced by the minutes, using the locale's alternative numeric symbols.\r
+    %OS is replaced by the seconds, using the locale's alternative numeric symbols.\r
+    %Ou is replaced by the ISO 8601 weekday as a number in the locale's\r
         alternative representation, where Monday is 1.\r
-    %OU is replaced by the week number, using the locale\92s alternative numeric symbols.\r
-    %OV is replaced by the ISO 8601 week number, using the locale\92s alternative\r
+    %OU is replaced by the week number, using the locale's alternative numeric symbols.\r
+    %OV is replaced by the ISO 8601 week number, using the locale's alternative\r
         numeric symbols.\r
-    %Ow is replaced by the weekday as a number, using the locale\92s alternative\r
+    %Ow is replaced by the weekday as a number, using the locale's alternative\r
         numeric symbols.\r
-    %OW is replaced by the week number of the year, using the locale\92s\r
+    %OW is replaced by the week number of the year, using the locale's\r
         alternative numeric symbols.\r
-    %Oy is replaced by the last 2 digits of the year, using the locale\92s\r
+    %Oy is replaced by the last 2 digits of the year, using the locale's\r
         alternative numeric symbols.\r
 \r
     %g, %G, and %V give values according to the ISO 8601 week-based year. In\r
@@ -358,7 +364,7 @@ struct tm  * EFIAPI localtime(const time_t *timer);
               character. Otherwise, zero is returned and the contents of the\r
               array are indeterminate.\r
 **/\r
-size_t EFIAPI strftime( char * __restrict s, size_t maxsize,\r
+size_t strftime( char * __restrict s, size_t maxsize,\r
                       const char * __restrict format,\r
                       const struct tm * __restrict timeptr);\r
 \r
@@ -367,6 +373,6 @@ char *strptime(const char *, const char * format, struct tm*);
 \r
 /* #################  Implementation Functions  ########################### */\r
 \r
-clock_t EFIAPI __getCPS(void);\r
+clock_t __getCPS(void);\r
 \r
 #endif  /* _TIME_H */\r
index fc8d7381b760864d33e6a5eb1a5893a9578f14da..df78690525139b7076bc319b293517a846eedd39 100644 (file)
 \r
 \r
 __BEGIN_DECLS\r
+int             dup(int);\r
 int             rename(const char *, const char *);\r
 \r
+/* Functions implemented for compatibility. */\r
+int             getopt(int, char * const [], const char *);\r
+extern   char  *optarg;     /* getopt(3) external variables */\r
+extern   int    optind;\r
+pid_t           getpgrp(void);\r
+pid_t           tcgetpgrp(int);\r
+char           *getpass(const char *);\r
+\r
 // Networking\r
 long            gethostid(void);\r
 int             gethostname(char *, size_t);\r
@@ -37,15 +46,20 @@ int             setdomainname(const char *, size_t);
 int             sethostid(long);\r
 int             sethostname(const char *, size_t);\r
 \r
+/*  Stub functions implemented for porting ease.\r
+    These functions always fail or return NULL.\r
+*/\r
+__aconst char  *getlogin(void);\r
+pid_t           fork(void);\r
+uid_t           getuid(void);\r
+\r
 // For Future implementation\r
-__dead   void   _exit(int) __attribute__((__noreturn__));\r
 ssize_t         pread(int, void *, size_t, off_t);\r
 ssize_t         pwrite(int, const void *, size_t, off_t);\r
 int             syscall(int, ...);\r
-int             dup(int);\r
-pid_t           fork(void);\r
 \r
-// The following *nix functions are not implemented\r
+#if 0   // The following functions are not implemented\r
+__dead   void   _exit(int) __attribute__((__noreturn__));\r
 unsigned int    alarm(unsigned int);\r
 int             chown(const char *, uid_t, gid_t);\r
 size_t          confstr(int, char *, size_t);\r
@@ -60,11 +74,8 @@ gid_t           getegid(void);
 uid_t           geteuid(void);\r
 gid_t           getgid(void);\r
 int             getgroups(int, gid_t []);\r
-__aconst char  *getlogin(void);\r
-pid_t           getpgrp(void);\r
 pid_t           getpid(void);\r
 pid_t           getppid(void);\r
-uid_t           getuid(void);\r
 int             link(const char *, const char *);\r
 long            pathconf(const char *, int);\r
 int             pause(void);\r
@@ -75,18 +86,14 @@ pid_t           setsid(void);
 int             setuid(uid_t);\r
 unsigned int    sleep(unsigned int);\r
 long            sysconf(int);\r
-pid_t           tcgetpgrp(int);\r
+\r
 int             tcsetpgrp(int, pid_t);\r
 __aconst char  *ttyname(int);\r
 \r
-int             getopt(int, char * const [], const char *);\r
-\r
-extern   char  *optarg;     /* getopt(3) external variables */\r
 extern   int    opterr;\r
-extern   int    optind;\r
 extern   int    optopt;\r
-extern   int    optreset;   /* getopt(3) external variable */\r
-extern   char  *suboptarg;  /* getsubopt(3) external variable */\r
+extern   int    optreset;\r
+extern   char  *suboptarg;\r
 \r
 int             setegid(gid_t);\r
 int             seteuid(uid_t);\r
@@ -97,7 +104,6 @@ int             chroot(const char *);
 int             nice(int);\r
 __aconst char *crypt(const char *, const char *);\r
 int             encrypt(char *, int);\r
-char           *getpass(const char *);\r
 pid_t           getsid(pid_t);\r
 \r
 #ifndef intptr_t\r
@@ -164,6 +170,7 @@ int             undelete(const char *);
 int             rcmd_af(char **, int, const char *, const char *, const char *, int *, int);\r
 int             rresvport_af(int *, int);\r
 int             iruserok_sa(const void *, int, int, const char *, const char *);\r
+#endif  /* Unimplemented functions. */\r
 \r
 __END_DECLS\r
 \r
index 19d7963e2a5368ba08546596a1c989b16e1965be..08222fa2d6b813e020b607a1da962e7ef41e293b 100644 (file)
 /** maximum value for an object of type unsigned int **/\r
 #define __UINT_MAX    0xffffffff // 2^32 - 1\r
 \r
-/** minimum value for an object of type long int **/\r
-#define __LONG_MIN    (-2147483647L - 1L) // -(2^31 - 1)\r
-\r
-/** maximum value for an object of type long int **/\r
-#define __LONG_MAX    +2147483647L // 2^31 - 1\r
-\r
-/** maximum value for an object of type unsigned long int **/\r
-#define __ULONG_MAX   0xffffffff // 2^32 - 1\r
-\r
 /** minimum value for an object of type long long int **/\r
 //#define __LLONG_MIN   -9223372036854775808LL // -(2^63 - 1)\r
 //#define __LLONG_MIN   ((-9223372036854775807LL)-1) // -(2^63 - 1)\r
@@ -71,7 +62,6 @@
 #define __SHORT_BIT     16\r
 #define __WCHAR_BIT     16\r
 #define __INT_BIT       32\r
-#define __LONG_BIT      32    /* Compiler dependent */\r
 #define __LONG_LONG_BIT 64\r
 \r
 #endif    /* _MACHINE_LIMITS_H */\r
index 5fee723f85c054a49193d4d135ffa22389619b15..c891e3bfaf2a3a81dbf02b3d078a16d93f598e9b 100644 (file)
 [LibraryClasses]\r
   LibC\r
   LibCType\r
-\r
-################################################################\r
-#\r
-# The Build Options, below, are only used when building the C library.\r
-# DO NOT use them when building your application!\r
-# Nasty things could happen if you do.\r
-#\r
-[BuildOptions]\r
-  GCC:*_*_*_CC_FLAGS    = -fno-builtin\r
index ebfc330fe9a3e8e0de887039c64efa00505a8606..2131d4b5c1b8af28eb50c4d610fe12397216ebc1 100644 (file)
@@ -42,6 +42,8 @@
   NetBSD: _wcstoul.h,v 1.3 2005/11/29 03:11:59 christos Exp\r
  */\r
 \r
+#include <Library/BaseLib.h>\r
+\r
 /*\r
  * function template for wcstoul, wcstoull and wcstoumax.\r
  *\r
@@ -102,8 +104,8 @@ _FUNCNAME(
   /*\r
    * See strtoul for comments as to the logic used.\r
    */\r
-  cutoff = __wUINT_MAX / (__wUINT)base;\r
-  cutlim = (int)(__wUINT_MAX % (__wUINT)base);\r
+  cutoff = (__wUINT)DivU64x32 ((UINT64) __wUINT_MAX, (UINT32) base);\r
+  cutlim = (int) ModU64x32 ((UINT64) __wUINT_MAX, (UINT32) base);\r
   for (acc = 0, any = 0;; wc = (wint_t) *s++) {\r
     i = __wctoint((wchar_t)wc);\r
     if (i == -1) {\r
index 6d57cd6c0972390fb88bc644878d8a2955b420f2..0a73898e6190aca8674efd093918709cb6fc08e0 100644 (file)
@@ -137,7 +137,7 @@ wcrtomb(
   /* ps appears to be unused */\r
 \r
   if (s == NULL)\r
-    return 0;\r
+    return 1;     /* Spec. says this should be 1. */\r
 \r
   *s = (char) wchar;\r
   return 1;\r
@@ -150,7 +150,12 @@ wctomb(
   )\r
 {\r
 \r
-  /* s may be NULL */\r
+  /*\r
+    If s is NULL just return if MB Characters have state\r
+    dependent encodings.\r
+  */\r
+  if (s == NULL)\r
+    return 0;\r
 \r
   return (int)wcrtomb(s, wchar, NULL);\r
 }\r
@@ -176,8 +181,10 @@ mbsrtowcs(
   if (n != 0) {\r
     if (pwcs != NULL) {\r
       do {\r
-        if ((*pwcs++ = (wchar_t) *(*s)++) == 0)\r
+        if ((*pwcs++ = (wchar_t) *(*s)++) == 0) {\r
+          *s = NULL;\r
           break;\r
+        }\r
         count++;\r
       } while (--n != 0);\r
     } else {\r
@@ -232,8 +239,10 @@ wcsrtombs(
 \r
   if (n != 0) {\r
     do {\r
-      if ((*s++ = (char) *(*pwcs)++) == 0)\r
+      if ((*s++ = (char) *(*pwcs)++) == 0) {\r
+        *pwcs = NULL;\r
         break;\r
+      }\r
       count++;\r
     } while (--n != 0);\r
   }\r
@@ -266,7 +275,13 @@ btowc(int c)
 int\r
 wctob(wint_t c)\r
 {\r
-  if (c == WEOF || c & ~0xFF)\r
+  /*  wctob needs to be consistent with wcrtomb.\r
+      if wcrtomb says that a character is representable in 1 byte,\r
+      which this implementation always says, then wctob needs to\r
+      also represent the character as 1 byte.\r
+  */\r
+  if (c == WEOF) {\r
     return EOF;\r
-  return (int)c;\r
+  }\r
+  return (int)(c & 0xFF);\r
 }\r
index 47103ce388a31620fa675291025feff45144c78c..3a5cca5b2461cc379a8a41c0204c7b76bff51243 100644 (file)
@@ -8,13 +8,14 @@
   This program and the accompanying materials are licensed and made available under\r
   the terms and conditions of the BSD License that accompanies this distribution.\r
   The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
+  http://opensource.org/licenses/bsd-license.\r
 \r
   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 **/\r
 #include  <Uefi.h>\r
 #include  <Library/UefiLib.h>\r
+#include  <Library/DebugLib.h>\r
 \r
 #include  <Library/ShellCEntryLib.h>\r
 #include  <Library/MemoryAllocationLib.h>\r
@@ -40,23 +41,30 @@ void __main()
   ;\r
 }\r
 \r
-static\r
+/** Clean up data as required by the exit() function.\r
+\r
+**/\r
 void\r
-FinalCleanup( void )\r
+exitCleanup(INTN ExitVal)\r
 {\r
+  void (*CleanUp)(void);   // Pointer to Cleanup Function\r
   int i;\r
 \r
-  /* Close any open files */\r
-  for(i = OPEN_MAX - 1; i >= 0; --i) {\r
-    (void)close(i);   // Close properly handles closing a closed file.\r
+  if(gMD != NULL) {\r
+    gMD->ExitValue = (int)ExitVal;\r
+    CleanUp = gMD->cleanup; // Preserve the pointer to the Cleanup Function\r
+\r
+    // Call all registered atexit functions in reverse order\r
+    i = gMD->num_atexit;\r
+    if( i > 0) {\r
+      do {\r
+        (gMD->atexit_handler[--i])();\r
+      } while( i > 0);\r
   }\r
 \r
-  /* Free the global MainData structure */\r
-  if(gMD != NULL) {\r
-    if(gMD->NCmdLine != NULL) {\r
-      FreePool( gMD->NCmdLine );\r
+    if (CleanUp != NULL) {\r
+      CleanUp();\r
     }\r
-    FreePool( gMD );\r
   }\r
 }\r
 \r
@@ -71,6 +79,13 @@ ArgvConvert(UINTN Argc, CHAR16 **Argv)
   char   *string;\r
   INTN    nArgvSize;  /* Cumulative size of narrow Argv[i] */\r
 \r
+DEBUG_CODE_BEGIN();\r
+  Print(L"ArgvConvert called with %d arguments.\n", Argc);\r
+  for(count = 0; count < ((Argc > 5)? 5: Argc); ++count) {\r
+    Print(L"Argument[%d] = \"%s\".\n", count, Argv[count]);\r
+  }\r
+DEBUG_CODE_END();\r
+\r
   nArgvSize = Argc;\r
   /* Determine space needed for narrow Argv strings. */\r
   for(count = 0; count < Argc; ++count) {\r
@@ -98,6 +113,7 @@ ArgvConvert(UINTN Argc, CHAR16 **Argv)
     nArgv[count] = string;\r
     AVsz = wcstombs(string, Argv[count], nArgvSize);\r
     string[AVsz] = 0;   /* NULL terminate the argument */\r
+    DEBUG((DEBUG_INFO, "Cvt[%d] %d \"%s\" --> \"%a\"\n", (INT32)count, (INT32)AVsz, Argv[count], nArgv[count]));\r
     string += AVsz + 1;\r
     nArgvSize -= AVsz + 1;\r
     if(nArgvSize < 0) {\r
@@ -119,7 +135,7 @@ ShellAppMain (
   struct __filedes   *mfd;\r
   char              **nArgv;\r
   INTN   ExitVal;\r
-  INTN   i;\r
+  int                 i;\r
 \r
   ExitVal = (INTN)RETURN_SUCCESS;\r
   gMD = AllocateZeroPool(sizeof(struct __MainData));\r
@@ -132,7 +148,6 @@ ShellAppMain (
     _fltused              = 1;\r
     errno                 = 0;\r
     EFIerrno              = 0;\r
-    gMD->FinalCleanup     = &FinalCleanup;\r
 \r
 #ifdef NT32dvm\r
     gMD->ClocksPerSecond  = 1;  // For NT32 only\r
@@ -166,10 +181,33 @@ ShellAppMain (
       ExitVal = (INTN)RETURN_INVALID_PARAMETER;\r
     }\r
     else {\r
-      ExitVal = (INTN)main( (int)Argc, nArgv);\r
+      if( setjmp(gMD->MainExit) == 0) {\r
+        ExitVal = (INTN)main( (int)Argc, gMD->NArgV);\r
+        exitCleanup(ExitVal);\r
+      }\r
+      /* You reach here if:\r
+          * normal return from main()\r
+          * call to _Exit(), either directly or through exit().\r
+      */\r
+      ExitVal = (INTN)gMD->ExitValue;\r
+    }\r
+\r
+    if( ExitVal == EXIT_FAILURE) {\r
+      ExitVal = RETURN_ABORTED;\r
+    }\r
+\r
+    /* Close any open files */\r
+    for(i = OPEN_MAX - 1; i >= 0; --i) {\r
+      (void)close(i);   // Close properly handles closing a closed file.\r
+    }\r
+\r
+    /* Free the global MainData structure */\r
+    if(gMD != NULL) {\r
+      if(gMD->NCmdLine != NULL) {\r
+        FreePool( gMD->NCmdLine );\r
+      }\r
+      FreePool( gMD );\r
   }\r
   }\r
-  exit((int)ExitVal);\r
-  /* Not Reached */\r
   return ExitVal;\r
 }\r
index 6bb53d6abd7d81f1a7dece3cf53179306f8f4a26..a20a656ef0a2889661f7e1476bfe696b0a4f512d 100644 (file)
@@ -18,7 +18,6 @@
 #include  <stdlib.h>\r
 \r
 void\r
-EFIAPI\r
 __assert(const char *func, const char *file, int line, const char *failedexpr)\r
 {\r
   if (func == NULL)\r
index d0478e2c1b1573f2821f0a6b3f50681c6b2b0089..86b484609851452839cab4a636f508f600aebafc 100644 (file)
@@ -16,7 +16,6 @@ extern int internal_FPU_rmode( void );
 static INT8  rmode[] = { 1, 3, 2, 0 };\r
 \r
 int\r
-EFIAPI\r
 __flt_rounds ( void )\r
 {\r
   return rmode[ internal_FPU_rmode() ];\r
index 537fe9cd426122175ed694a7c2f3d1d06b1ebd76..9fc6b9b7be88759badc57d61092e1a2cc8107b6c 100644 (file)
   LibStdLib\r
   LibStdio\r
   LibString\r
-\r
-################################################################\r
-#\r
-# The Build Options, below, are only used when building the Socket library.\r
-# DO NOT use them when building your application!\r
-# Nasty things could happen if you do.\r
-#\r
-#[BuildOptions]\r
-#  MSFT:*_*_IA32_CC_FLAGS = /GL-\r
index 8472d0ef4c95a36c01f78be1df107f45a9420959..40807279c930c422a50b6fd7cc8e39dd457fa4f8 100644 (file)
 #include  <stdlib.h>\r
 #include  <MainData.h>\r
 \r
+/** Internal worker function used by exit().\r
+**/\r
+void  exitCleanup(INTN ExitVal);\r
+\r
 /* #################  Public Functions  ################################### */\r
 \r
 /** The abort function causes abnormal program termination to occur, unless\r
@@ -92,24 +96,7 @@ atexit(void (*handler)(void))
 void\r
 exit(int status)\r
 {\r
-  void (*CleanUp)(void);   // Pointer to Cleanup Function\r
-  int   i;\r
-\r
-  if(gMD != NULL) {\r
-    CleanUp = gMD->cleanup; // Preserve the pointer to the Cleanup Function\r
-\r
-  // Call all registered atexit functions in reverse order\r
-    i = gMD->num_atexit;\r
-  if( i > 0) {\r
-    do {\r
-      (gMD->atexit_handler[--i])();\r
-    } while( i > 0);\r
-  }\r
-\r
-    if (CleanUp != NULL) {\r
-      CleanUp();\r
-    }\r
-  }\r
+  exitCleanup((INTN) status);\r
   _Exit(status);\r
 }\r
 \r
@@ -129,17 +116,12 @@ exit(int status)
 void\r
 _Exit(int status)\r
 {\r
-  RETURN_STATUS ExitVal = (RETURN_STATUS)status;\r
-\r
-  if( ExitVal == EXIT_FAILURE) {\r
-    ExitVal = RETURN_ABORTED;\r
-  }\r
-\r
-  if(gMD->FinalCleanup != NULL) {\r
-    gMD->FinalCleanup();  // gMD does not exist when this returns.\r
-  }\r
+  gMD->ExitValue = status;          // Save our exit status.  Allows a status of 0.\r
+  longjmp(gMD->MainExit, 0x55);     // Get out of here.  longjmp can't return 0. Use 0x55 for a non-zero value.\r
 \r
-  gBS->Exit(gImageHandle, ExitVal, 0, NULL);   /* abort() */\r
+#ifdef __GNUC__\r
+  __builtin__Exit(status);         /* Keep GCC happy - never reached */\r
+#endif\r
 }\r
 \r
 /** If string is a null pointer, the system function determines whether the\r
index 058ad04959ba30c8fa3ccc9488d7e431814cd76d..97e52eb1bd3be8e4ab2838585873aa5fbd7501f7 100644 (file)
@@ -8,7 +8,7 @@
     - atol: strtol(nptr, (char **)NULL, 10)\r
     - atoll: strtoll(nptr, (char **)NULL, 10)\r
 \r
-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials are licensed and made available under\r
   the terms and conditions of the BSD License that accompanies this distribution.\r
   The full text of the license may be found at\r
@@ -120,7 +120,7 @@ atoll(const char *nptr)
 static int\r
 Digit2Val( int c)\r
 {\r
-  if(__isHexLetter(c)) {  /* If c is one of [A-Fa-f]... */\r
+  if(isalpha(c)) {  /* If c is one of [A-Za-z]... */\r
     c = toupper(c) - 7;   // Adjust so 'A' is ('9' + 1)\r
   }\r
   return c - '0';   // Value returned is between 0 and 35, inclusive.\r
@@ -183,13 +183,18 @@ Digit2Val( int c)
 long\r
 strtol(const char * __restrict nptr, char ** __restrict endptr, int base)\r
 {\r
+  const char *pEnd;\r
   long        Result = 0;\r
   long        Previous;\r
   int         temp;\r
   BOOLEAN     Negative = FALSE;\r
 \r
+  pEnd = nptr;\r
+\r
   if((base < 0) || (base == 1) || (base > 36)) {\r
+    if(endptr != NULL) {\r
     *endptr = NULL;\r
+    }\r
     return 0;\r
   }\r
   // Skip leading spaces.\r
@@ -204,9 +209,29 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
     Negative = TRUE;\r
     ++nptr;\r
   }\r
-  if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {\r
-    nptr += 2;\r
+\r
+  if(*nptr == '0') {  /* Might be Octal or Hex */\r
+    if(toupper(nptr[1]) == 'X') {   /* Looks like Hex */\r
+      if((base == 0) || (base == 16)) {\r
+        nptr += 2;  /* Skip the "0X"      */\r
+        base = 16;  /* In case base was 0 */\r
+      }\r
+    }\r
+    else {    /* Looks like Octal */\r
+      if((base == 0) || (base == 8)) {\r
+        ++nptr;     /* Skip the leading "0" */\r
+        base = 8;   /* In case base was 0   */\r
+      }\r
+    }\r
+  }\r
+  if(base == 0) {   /* If still zero then must be decimal */\r
+    base = 10;\r
+  }\r
+  if(*nptr  == '0') {\r
+    for( ; *nptr == '0'; ++nptr);  /* Skip any remaining leading zeros */\r
+    pEnd = nptr;\r
   }\r
+\r
   while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {\r
     Previous = Result;\r
     Result = (Result * base) + (long int)temp;\r
@@ -221,15 +246,15 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
       errno = ERANGE;\r
       break;\r
     }\r
-    ++nptr;\r
+    pEnd = ++nptr;\r
   }\r
   if(Negative) {\r
     Result = -Result;\r
   }\r
 \r
   // Save pointer to final sequence\r
-  if( endptr != NULL) {\r
-    *endptr = (char *)nptr;\r
+  if(endptr != NULL) {\r
+    *endptr = (char *)pEnd;\r
   }\r
   return Result;\r
 }\r
@@ -247,12 +272,17 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
 unsigned long\r
 strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)\r
 {\r
+  const char     *pEnd;\r
   unsigned long   Result = 0;\r
   unsigned long   Previous;\r
   int             temp;\r
 \r
+  pEnd = nptr;\r
+\r
   if((base < 0) || (base == 1) || (base > 36)) {\r
+    if(endptr != NULL) {\r
     *endptr = NULL;\r
+    }\r
     return 0;\r
   }\r
   // Skip leading spaces.\r
@@ -262,9 +292,29 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
   if(*nptr == '+') {\r
     ++nptr;\r
   }\r
-  if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {\r
-    nptr += 2;\r
+\r
+  if(*nptr == '0') {  /* Might be Octal or Hex */\r
+    if(toupper(nptr[1]) == 'X') {   /* Looks like Hex */\r
+      if((base == 0) || (base == 16)) {\r
+        nptr += 2;  /* Skip the "0X"      */\r
+        base = 16;  /* In case base was 0 */\r
+      }\r
+    }\r
+    else {    /* Looks like Octal */\r
+      if((base == 0) || (base == 8)) {\r
+        ++nptr;     /* Skip the leading "0" */\r
+        base = 8;   /* In case base was 0   */\r
+      }\r
+    }\r
+  }\r
+  if(base == 0) {   /* If still zero then must be decimal */\r
+    base = 10;\r
+  }\r
+  if(*nptr  == '0') {\r
+    for( ; *nptr == '0'; ++nptr);  /* Skip any remaining leading zeros */\r
+    pEnd = nptr;\r
   }\r
+\r
   while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {\r
     Previous = Result;\r
     Result = (Result * base) + (unsigned long)temp;\r
@@ -273,12 +323,12 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
       errno = ERANGE;\r
       break;\r
     }\r
-    ++nptr;\r
+    pEnd = ++nptr;\r
   }\r
 \r
   // Save pointer to final sequence\r
-  if( endptr != NULL) {\r
-    *endptr = (char *)nptr;\r
+  if(endptr != NULL) {\r
+    *endptr = (char *)pEnd;\r
   }\r
   return Result;\r
 }\r
@@ -297,13 +347,18 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
 long long\r
 strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)\r
 {\r
+  const char *pEnd;\r
   long long   Result = 0;\r
   long long   Previous;\r
   int         temp;\r
   BOOLEAN     Negative = FALSE;\r
 \r
+  pEnd = nptr;\r
+\r
   if((base < 0) || (base == 1) || (base > 36)) {\r
+    if(endptr != NULL) {\r
     *endptr = NULL;\r
+    }\r
     return 0;\r
   }\r
   // Skip leading spaces.\r
@@ -318,9 +373,29 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
     Negative = TRUE;\r
     ++nptr;\r
   }\r
-  if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {\r
-    nptr += 2;\r
+\r
+  if(*nptr == '0') {  /* Might be Octal or Hex */\r
+    if(toupper(nptr[1]) == 'X') {   /* Looks like Hex */\r
+      if((base == 0) || (base == 16)) {\r
+        nptr += 2;  /* Skip the "0X"      */\r
+        base = 16;  /* In case base was 0 */\r
+      }\r
+    }\r
+    else {    /* Looks like Octal */\r
+      if((base == 0) || (base == 8)) {\r
+        ++nptr;     /* Skip the leading "0" */\r
+        base = 8;   /* In case base was 0   */\r
+      }\r
+    }\r
+  }\r
+  if(base == 0) {   /* If still zero then must be decimal */\r
+    base = 10;\r
+  }\r
+  if(*nptr  == '0') {\r
+    for( ; *nptr == '0'; ++nptr);  /* Skip any remaining leading zeros */\r
+    pEnd = nptr;\r
   }\r
+\r
   while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {\r
     Previous = Result;\r
     Result = (Result * base) + (long long int)temp;\r
@@ -335,15 +410,15 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
       errno = ERANGE;\r
       break;\r
     }\r
-    ++nptr;\r
+    pEnd = ++nptr;\r
   }\r
   if(Negative) {\r
     Result = -Result;\r
   }\r
 \r
   // Save pointer to final sequence\r
-  if( endptr != NULL) {\r
-    *endptr = (char *)nptr;\r
+  if(endptr != NULL) {\r
+    *endptr = (char *)pEnd;\r
   }\r
   return Result;\r
 }\r
@@ -361,12 +436,17 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
 unsigned long long\r
 strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)\r
 {\r
+  const char           *pEnd;\r
   unsigned long long    Result = 0;\r
   unsigned long long    Previous;\r
   int                   temp;\r
 \r
+  pEnd = nptr;\r
+\r
   if((base < 0) || (base == 1) || (base > 36)) {\r
+    if(endptr != NULL) {\r
     *endptr = NULL;\r
+    }\r
     return 0;\r
   }\r
   // Skip leading spaces.\r
@@ -376,9 +456,29 @@ strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
   if(*nptr == '+') {\r
     ++nptr;\r
   }\r
-  if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {\r
-    nptr += 2;\r
+\r
+  if(*nptr == '0') {  /* Might be Octal or Hex */\r
+    if(toupper(nptr[1]) == 'X') {   /* Looks like Hex */\r
+      if((base == 0) || (base == 16)) {\r
+        nptr += 2;  /* Skip the "0X"      */\r
+        base = 16;  /* In case base was 0 */\r
+      }\r
+    }\r
+    else {    /* Looks like Octal */\r
+      if((base == 0) || (base == 8)) {\r
+        ++nptr;     /* Skip the leading "0" */\r
+        base = 8;   /* In case base was 0   */\r
+      }\r
+    }\r
+  }\r
+  if(base == 0) {   /* If still zero then must be decimal */\r
+    base = 10;\r
+  }\r
+  if(*nptr  == '0') {\r
+    for( ; *nptr == '0'; ++nptr);  /* Skip any remaining leading zeros */\r
+    pEnd = nptr;\r
   }\r
+\r
   while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {\r
     Previous = Result;\r
     Result = (Result * base) + (unsigned long long)temp;\r
@@ -387,12 +487,12 @@ strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
       errno = ERANGE;\r
       break;\r
     }\r
-    ++nptr;\r
+    pEnd = ++nptr;\r
   }\r
 \r
   // Save pointer to final sequence\r
-  if( endptr != NULL) {\r
-    *endptr = (char *)nptr;\r
+  if(endptr != NULL) {\r
+    *endptr = (char *)pEnd;\r
   }\r
   return Result;\r
 }\r
index 21d1c1f4aa9735c0d377dc16e148a74e2ac0f8be..ce1c3052cbba68e9d5f0a89f86b4d7fd42a33b8c 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  Standard C library: StdLib implementations.\r
 #\r
-#  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -36,6 +36,8 @@
   strtoumax.c\r
   Xabs.c\r
   Xdiv.c\r
+  realpath.c\r
+  setprogname.c\r
 \r
 [Packages]\r
   StdLib/StdLib.dec\r
@@ -53,6 +55,7 @@
   LibC\r
   LibCType\r
   LibSignal\r
+  PathLib\r
 \r
 ################################################################\r
 #\r
diff --git a/StdLib/LibC/StdLib/realpath.c b/StdLib/LibC/StdLib/realpath.c
new file mode 100644 (file)
index 0000000..b9f674d
--- /dev/null
@@ -0,0 +1,57 @@
+/** @file\r
+  Implement the realpath function.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <LibConfig.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PathLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <errno.h>\r
+\r
+/**\r
+  The realpath() function shall derive, from the pathname pointed to by \r
+  file_name, an absolute pathname that names the same file, whose resolution \r
+  does not involve '.', '..', or symbolic links. The generated pathname shall\r
+  be stored as a null-terminated string, up to a maximum of {PATH_MAX} bytes,\r
+  in the buffer pointed to by resolved_name.\r
+\r
+  If resolved_name is a null pointer, the behavior of realpath() is \r
+  implementation-defined.\r
+\r
+  @param[in] file_name            The filename to convert.\r
+  @param[in,out] resolved_name    The resultant name.\r
+\r
+  @retval NULL                    An error occured.\r
+  @return resolved_name.\r
+**/\r
+char *\r
+realpath(\r
+  char *file_name, \r
+  char *resolved_name\r
+  )\r
+{\r
+  CHAR16 *Temp;\r
+  if (file_name == NULL || resolved_name == NULL) {\r
+    errno = EINVAL;\r
+    return (NULL);\r
+  }\r
+  Temp = AllocateZeroPool((1+AsciiStrLen(file_name))*sizeof(CHAR16));\r
+  if (Temp == NULL) {\r
+    errno = ENOMEM;\r
+    return (NULL);\r
+  }\r
+  AsciiStrToUnicodeStr(file_name, Temp);\r
+  PathCleanUpDirectories(Temp);\r
+  UnicodeStrToAsciiStr(Temp, resolved_name);\r
+  return (resolved_name);\r
+}
\ No newline at end of file
diff --git a/StdLib/LibC/StdLib/setprogname.c b/StdLib/LibC/StdLib/setprogname.c
new file mode 100644 (file)
index 0000000..3f2bc53
--- /dev/null
@@ -0,0 +1,64 @@
+/** @file setprogname and getprogname\r
+\r
+  $NetBSD: setprogname.c,v 1.5 2008/04/28 20:24:12 martin Exp $\r
+\r
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to The NetBSD Foundation\r
+ * by Todd Vierling.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\r
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+#include  <LibConfig.h>\r
+\r
+#ifndef HAVE_SETPROGNAME\r
+#include <string.h>\r
+\r
+static const char *__progname = NULL;\r
+\r
+void\r
+setprogname(const char *progname)\r
+{\r
+  __progname = strrchr(progname, '/');\r
+  if (__progname == NULL)\r
+    __progname = progname;\r
+  else\r
+    __progname++;\r
+}\r
+\r
+const char *\r
+getprogname(void)\r
+{\r
+  return __progname;\r
+}\r
+\r
+#endif\r
index 5bf64383d45956b7f26c88d440ec9b7777500a92..15658002a948d487cefe5d0eae6361979fafaa8e 100644 (file)
@@ -48,6 +48,8 @@ __RCSID("$NetBSD: strtoumax.c,v 1.1 2006/04/22 15:33:33 thorpej Exp $");
 #include <inttypes.h>\r
 #include <stddef.h>\r
 \r
+#include <Library/BaseLib.h>\r
+\r
 #ifdef __weak_alias\r
 __weak_alias(strtoumax, _strtoumax)\r
 #endif\r
@@ -98,8 +100,8 @@ strtoumax(const char *nptr, char **endptr, int base)
   if (base == 0)\r
     base = c == '0' ? 8 : 10;\r
 \r
-  cutoff = UINTMAX_MAX / (uintmax_t)base;\r
-  cutlim = (int)(UINTMAX_MAX % (uintmax_t)base);\r
+  cutoff = DivU64x32 ((UINT64) UINTMAX_MAX, (UINT32) base);\r
+  cutlim = (int) ModU64x32 ((UINT64) UINTMAX_MAX, (UINT32) base);\r
   for (acc = 0, any = 0;; c = (unsigned char) *s++) {\r
     if (isdigit(c))\r
       c -= '0';\r
index 9d2adef1f63739d85b3569879cbeee7ec579c9d4..6edc8867e8015bff39cdff7a2d90c98e3e39f20b 100644 (file)
@@ -72,6 +72,7 @@
 \r
   snprintf.c\r
   vsnprintf.c\r
+  fparseln.c\r
 \r
   # Wide character functions\r
   fgetwc.c            #\r
index 4d34497317bc062efa57056021d60a872edc9404..75a086b84b2ea16d13e24d8c879327ac170a7420 100644 (file)
@@ -104,7 +104,7 @@ freopen(const char *file, const char *mode, FILE *fp)
       (void) __sflush(fp);\r
     /* if close is NULL, closing is a no-op, hence pointless */\r
     isopen = fp->_close != NULL;\r
-    if ((wantfd = fp->_file) < 0 && isopen) {\r
+    if (((wantfd = fp->_file) >= 0) && isopen) {\r
       (void) (*fp->_close)(fp->_cookie);\r
       isopen = 0;\r
     }\r
@@ -127,7 +127,7 @@ freopen(const char *file, const char *mode, FILE *fp)
    * keep fp->_base: it may be the wrong size.  This loses the effect\r
    * of any setbuffer calls, but stdio has always done this before.\r
    */\r
-  if (isopen && f != wantfd)\r
+  if (isopen && (f != wantfd))\r
     (void) (*fp->_close)(fp->_cookie);\r
   if (fp->_flags & __SMBF)\r
     free((char *)fp->_bf._base);\r
index 7fc7e426616f428cbc62a14d89ce173da9dadad6..662d25f91a3ded9631e2bfafea7ce92cc3505f66 100644 (file)
@@ -238,6 +238,7 @@ fseeko(FILE *fp, off_t offset, int whence)
     fp->_r = (int)(n - o);\r
     if (HASUB(fp))\r
       FREEUB(fp);\r
+    WCIO_FREE(fp);    /* Should this really be unconditional??? */\r
     fp->_flags &= ~__SEOF;\r
     FUNLOCKFILE(fp);\r
     return (0);\r
@@ -261,6 +262,7 @@ fseeko(FILE *fp, off_t offset, int whence)
   fp->_p = fp->_bf._base;\r
   if (HASUB(fp))\r
     FREEUB(fp);\r
+  WCIO_FREE(fp);    /* Should this really be unconditional??? */\r
   fp->_flags &= ~__SEOF;\r
   n = (int)(target - curoff);\r
   if (n) {\r
@@ -290,9 +292,10 @@ dumb:
   /* success: clear EOF indicator and discard ungetc() data */\r
   if (HASUB(fp))\r
     FREEUB(fp);\r
+  WCIO_FREE(fp);    /* Should this really be unconditional??? */\r
   fp->_p = fp->_bf._base;\r
   fp->_r = 0;\r
-  /* fp->_w = 0; */ /* unnecessary (I think...) */\r
+  fp->_w = 0;\r
   fp->_flags &= ~__SEOF;\r
   FUNLOCKFILE(fp);\r
 //Print(L"%a: %d\n", __func__, __LINE__);\r
index 1bd7dd3924caac02e49c08767f0deea91e3b1e54..7b1c564c9acd026be0ebd8e940c558908e66041a 100644 (file)
@@ -45,7 +45,7 @@
 #include "nbtool_config.h"\r
 #endif\r
 \r
-#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP || !HAVE_MKDTEMP\r
+#if !defined(HAVE_NBTOOL_CONFIG_H) || !defined(HAVE_MKSTEMP) || !defined(HAVE_MKDTEMP)\r
 \r
 #include <sys/EfiCdefs.h>\r
 #if defined(LIBC_SCCS) && !defined(lint)\r
index f9eaba99896a4d83c05e337f3c37d52fe66979d8..262deb36116c32386cef59eba1c774d12c5d787e 100644 (file)
@@ -64,11 +64,11 @@ extern int      _fwalk(int (*)(FILE *));
 extern char    *_mktemp(char *);\r
 extern int      __swsetup(FILE *);\r
 extern int      __sflags(const char *, int *);\r
-extern int      __svfscanf(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_)\r
+extern int      __svfscanf(FILE * __restrict, const char * __restrict, va_list)\r
                             __attribute__((__format__(__scanf__, 2, 0)));\r
-extern int      __svfscanf_unlocked(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_)\r
+extern int      __svfscanf_unlocked(FILE * __restrict, const char * __restrict, va_list)\r
                             __attribute__((__format__(__scanf__, 2, 0)));\r
-extern int      __vfprintf_unlocked(FILE * __restrict, const char * __restrict, _BSD_VA_LIST_);\r
+extern int      __vfprintf_unlocked(FILE * __restrict, const char * __restrict, va_list);\r
 \r
 \r
 extern int      __sdidinit;\r
@@ -80,8 +80,8 @@ extern wint_t   __fputwc_unlock(wchar_t, FILE *);
 \r
 extern char    *__fgetstr(FILE * __restrict, size_t * __restrict, int);\r
 extern int      __slbexpand(FILE *, size_t);\r
-extern int      __vfwprintf_unlocked(FILE *, const wchar_t *, _BSD_VA_LIST_);\r
-extern int      __vfwscanf_unlocked(FILE * __restrict, const wchar_t * __restrict, _BSD_VA_LIST_);\r
+extern int      __vfwprintf_unlocked(FILE *, const wchar_t *, va_list);\r
+extern int      __vfwscanf_unlocked(FILE * __restrict, const wchar_t * __restrict, va_list);\r
 \r
 /*\r
  * Return true iff the given FILE cannot be written now.\r
index 7ea578ce4a9e0d67294cfcebecf66cb620bf7445..d2962214ddb896f955097d3bb7517263290df120 100644 (file)
@@ -34,7 +34,7 @@
 #include "nbtool_config.h"\r
 #endif\r
 \r
-#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP\r
+#if !defined(HAVE_NBTOOL_CONFIG_H) || !defined(HAVE_MKSTEMP)\r
 \r
 #include  <sys/EfiCdefs.h>\r
 #if defined(LIBC_SCCS) && !defined(lint)\r
index 9527a4b3f691a63c9bf37ca98006c7946489ec2a..761f67f88cf68484be593296aa132c8380c25ba8 100644 (file)
@@ -1,6 +1,13 @@
-/*  $NetBSD: setbuffer.c,v 1.10 2003/08/07 16:43:31 agc Exp $ */\r
+/*\r
+    Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
+    This program and the accompanying materials are licensed and made available\r
+    under the terms and conditions of the BSD License that accompanies this\r
+    distribution.  The full text of the license may be found at\r
+    http://opensource.org/licenses/bsd-license.\r
+\r
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
-/*-\r
  * Copyright (c) 1990, 1993\r
  *  The Regents of the University of California.  All rights reserved.\r
  *\r
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
  * SUCH DAMAGE.\r
- */\r
+\r
+    NetBSD: setbuffer.c,v 1.10 2003/08/07 16:43:31 agc Exp\r
+    setbuffer.c 8.1 (Berkeley) 6/4/93\r
+*/\r
 #include  <LibConfig.h>\r
 #include <sys/EfiCdefs.h>\r
-#if defined(LIBC_SCCS) && !defined(lint)\r
-#if 0\r
-static char sccsid[] = "@(#)setbuffer.c 8.1 (Berkeley) 6/4/93";\r
-#else\r
-__RCSID("$NetBSD: setbuffer.c,v 1.10 2003/08/07 16:43:31 agc Exp $");\r
-#endif\r
-#endif /* LIBC_SCCS and not lint */\r
 \r
 #include <assert.h>\r
 #include <errno.h>\r
index 3c5332ac4aab50d5c7cb68b498832b8c41a89654..0554edb64516656572f2d811ddbdd54061280e49 100644 (file)
@@ -1056,8 +1056,6 @@ reswitch: switch (ch) {
         xdigs = xdigs_upper;\r
         expchar = 'P';\r
       }\r
-      if (prec >= 0)\r
-        prec++;\r
       if (flags & LONGDBL) {\r
         fparg.ldbl = GETARG(long double);\r
         dtoaresult =\r
@@ -1092,10 +1090,8 @@ reswitch: switch (ch) {
     case 'e':\r
     case 'E':\r
       expchar = ch;\r
-      if (prec < 0) /* account for digit before decpt */\r
-        prec = DEFPREC + 1;\r
-      else\r
-        prec++;\r
+      if (prec < 0)\r
+        prec = DEFPREC;\r
       goto fp_begin;\r
     case 'f':\r
     case 'F':\r
@@ -1165,10 +1161,8 @@ fp_common:
     case 'e':\r
     case 'E':\r
       expchar = ch;\r
-      if (prec < 0) /* account for digit before decpt */\r
-        prec = DEFPREC /* + 1*/ ;\r
-      else\r
-        prec++;\r
+      if (prec < 0)\r
+        prec = DEFPREC;\r
       goto fp_begin;\r
     case 'f':\r
     case 'F':\r
@@ -1242,16 +1236,21 @@ fp_begin:
           /*\r
            * Make %[gG] smell like %[eE], but\r
            * trim trailing zeroes if no # flag.\r
+           *\r
+           * Note: The precision field used with [gG] is the number significant\r
+           * digits to print.  When converting to [eE] the digit before the\r
+           * decimal must not be included in the precision value.\r
            */\r
           if (!(flags & ALT))\r
-            prec = ndig;\r
+            prec = ndig - 1;\r
         }\r
       }\r
       if (expchar) {\r
+        dprec = prec; /* In some cases dprec will not be set.  Make sure it is set now */\r
         expsize = exponent(expstr, expt - 1, expchar);\r
-        size = expsize + prec;\r
-        if (prec > 1 || flags & ALT)\r
-          ++size;\r
+        size = expsize + prec + 1; /* Leading digit + exponent string + precision */\r
+        if (prec >= 1 || flags & ALT)\r
+          ++size; /* Decimal point is added to character count */\r
       } else {\r
         /* space for digits before decimal point */\r
         if (expt > 0)\r
@@ -1322,7 +1321,7 @@ fp_begin:
        * defined manner.''\r
        *  -- ANSI X3J11\r
        */\r
-      ujval = (uintmax_t)GETARG(void *);\r
+      ujval = (uintmax_t) (UINTN) GETARG(void *);\r
       base = 16;\r
       xdigs = xdigs_lower;\r
       flags = flags | INTMAXT;\r
@@ -1332,7 +1331,7 @@ fp_begin:
       flags |= LONGINT;\r
       /*FALLTHROUGH*/\r
     case 's':\r
-      if ((flags & LONGINT) != MULTI) {\r
+      if (((flags & LONGINT) ? 1:0) != MULTI) {\r
         if ((result = GETARG(CHAR_T *)) == NULL)\r
           result = STRCONST("(null)");\r
       } else {\r
@@ -1538,7 +1537,7 @@ number:     if ((dprec = prec) >= 0)
         PRINTANDPAD(result, convbuf + ndig, prec,\r
             zeroes);\r
       } else {  /* %[eE] or sufficiently long %[gG] */\r
-        if (prec > 1 || flags & ALT) {\r
+        if (prec >= 1 || flags & ALT) {\r
           buf[0] = *result++;\r
           buf[1] = *decimal_point;\r
           PRINT(buf, 2);\r
@@ -2003,8 +2002,6 @@ cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch,
         *decpt = -ndigits + 1;\r
       bp += *decpt;\r
     }\r
-    if (value == 0) /* kludge for __dtoa irregularity */\r
-      rve = bp;\r
     while (rve < bp)\r
       *rve++ = '0';\r
   }\r
index 3d7404171b9d1cd1ce17c325d66116bbb7307ace..7bf3f666903c4d223bf74c6c24ecbfa088ca7e50 100644 (file)
@@ -198,7 +198,7 @@ literal:
         goto input_failure;\r
       if (wi != c) {\r
         ungetwc(wi, fp);\r
-        goto input_failure;\r
+        goto match_failure;\r
       }\r
       nread++;\r
       continue;\r
@@ -721,20 +721,19 @@ literal:
       if ((width = parsefloat(fp, buf, buf + width)) == 0)\r
         goto match_failure;\r
       if ((flags & SUPPRESS) == 0) {\r
-#ifdef notyet\r
+#ifdef REAL_LONG_DOUBLE_SUPPORT\r
         if (flags & LONGDBL) {\r
           long double res = wcstold(buf, &p);\r
           *va_arg(ap, long double *) = res;\r
         } else\r
 #endif\r
-        if (flags & LONG) {\r
+        if (flags & (LONG | LONGDBL)) {\r
           double res = wcstod(buf, &p);\r
           *va_arg(ap, double *) = res;\r
-#ifdef notyet\r
-        else {\r
+        }\r
+        else {\r
           float res = wcstof(buf, &p);\r
           *va_arg(ap, float *) = res;\r
-#endif\r
         }\r
 #ifdef DEBUG\r
         if (p - buf != width)\r
index 96d43ee7a03d1118000cac63c44f5e879298a1a8..46ebf3297062e8f392a67be7e05c5693123bb174 100644 (file)
@@ -50,7 +50,7 @@
 #include <stdio.h>\r
 \r
 int\r
-vprintf(char const *fmt, _BSD_VA_LIST_ ap)\r
+vprintf(char const *fmt, va_list ap)\r
 {\r
   _DIAGASSERT(fmt != NULL);\r
 \r
index 23385ba0d8d3fde1c41378cd94fac06382564b1b..16e06667bc391e9da072ffbecc767eb6e809564b 100644 (file)
@@ -54,7 +54,7 @@ __weak_alias(vsnprintf,_vsnprintf)
 #endif\r
 \r
 int\r
-vsnprintf(char *str, size_t n, const char *fmt, _BSD_VA_LIST_ ap)\r
+vsnprintf(char *str, size_t n, const char *fmt, va_list ap)\r
 {\r
   int ret;\r
   FILE f;\r
index 77a2887ea607099393deaeb23b337fc32e2911ac..a71dd6d3e59b72c65ef0a778e3bb76dad4629d77 100644 (file)
@@ -117,7 +117,7 @@ __weak_alias(vsnprintf_ss,_vsnprintf_ss)
 } while (/*CONSTCOND*/0)\r
 \r
 int\r
-vsnprintf_ss(char *sbuf, size_t slen, const char *fmt0, _BSD_VA_LIST_ ap)\r
+vsnprintf_ss(char *sbuf, size_t slen, const char *fmt0, va_list ap)\r
 {\r
   const char *fmt;  /* format string */\r
   int ch;     /* character from fmt */\r
index 4fb8d28155b21f7fee1e6497c1fd7a076e214abc..9534d95e1bafc45c9aa02cc8bc0c99d7a3d515c1 100644 (file)
@@ -53,7 +53,7 @@
 #include "local.h"\r
 \r
 int\r
-vsprintf(char *str, const char *fmt, _BSD_VA_LIST_ ap)\r
+vsprintf(char *str, const char *fmt, va_list ap)\r
 {\r
   int ret;\r
   FILE f;\r
index e656fe73f5059c5404a3f60cef00f29f437d5e34..b4980c7c1e880273203c169f1f5fdc1ea54cc070 100644 (file)
@@ -109,10 +109,15 @@ strcasecmp(const char *s1, const char *s2)
 {\r
   const unsigned char *us1 = (const unsigned char *)s1,\r
   *us2 = (const unsigned char *)s2;\r
+  int Difference;\r
 \r
-  while (tolower(*us1) == tolower(*us2++))\r
-    if (*us1++ == '\0')\r
+  while ( 0 == ( Difference = tolower(*us1) - tolower(*us2))) {\r
+    if (*us1 == 0) {\r
     return (0);\r
-  return (tolower(*us1) - tolower(*--us2));\r
+    }\r
+    us1 += 1;\r
+    us2 += 1;\r
+  }\r
+  return Difference;\r
 }\r
 \r
index b6ab66005199f056c5f7aae404c8142791cfdd2c..62db60e6a56279f99dcb702c4edc54ee4b23abbf 100644 (file)
@@ -33,6 +33,9 @@
   Searching.c\r
   ErrorList.c\r
   strncasecmp.c\r
+  strlcpy.c\r
+  strlcat.c\r
+  strsep.c\r
 \r
 [Packages]\r
   StdLib/StdLib.dec\r
diff --git a/StdLib/LibC/String/strlcat.c b/StdLib/LibC/String/strlcat.c
new file mode 100644 (file)
index 0000000..fc9aba7
--- /dev/null
@@ -0,0 +1,86 @@
+/*  $NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */\r
+/*  $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $  */\r
+\r
+/*\r
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE\r
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\r
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\r
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r
+ */\r
+#include  <LibConfig.h>\r
+\r
+#if !defined(_KERNEL) && !defined(_STANDALONE)\r
+#if HAVE_NBTOOL_CONFIG_H\r
+#include "nbtool_config.h"\r
+#endif\r
+\r
+#include <sys/cdefs.h>\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+__RCSID("$NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $");\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#ifdef _LIBC\r
+#include "namespace.h"\r
+#endif\r
+#include <sys/types.h>\r
+#include <assert.h>\r
+#include <string.h>\r
+\r
+#ifdef _LIBC\r
+# ifdef __weak_alias\r
+__weak_alias(strlcat, _strlcat)\r
+# endif\r
+#endif\r
+\r
+#else\r
+#include <lib/libkern/libkern.h>\r
+#endif /* !_KERNEL && !_STANDALONE */\r
+\r
+#ifndef HAVE_STRLCAT\r
+/*\r
+ * Appends src to string dst of size siz (unlike strncat, siz is the\r
+ * full size of dst, not space left).  At most siz-1 characters\r
+ * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).\r
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).\r
+ * If retval >= siz, truncation occurred.\r
+ */\r
+size_t\r
+strlcat(char *dst, const char *src, size_t siz)\r
+{\r
+  char *d = dst;\r
+  const char *s = src;\r
+  size_t n = siz;\r
+  size_t dlen;\r
+\r
+  _DIAGASSERT(dst != NULL);\r
+  _DIAGASSERT(src != NULL);\r
+\r
+  /* Find the end of dst and adjust bytes left but don't go past end */\r
+  while (n-- != 0 && *d != '\0')\r
+    d++;\r
+  dlen = d - dst;\r
+  n = siz - dlen;\r
+\r
+  if (n == 0)\r
+    return(dlen + strlen(s));\r
+  while (*s != '\0') {\r
+    if (n != 1) {\r
+      *d++ = *s;\r
+      n--;\r
+    }\r
+    s++;\r
+  }\r
+  *d = '\0';\r
+\r
+  return(dlen + (s - src)); /* count does not include NUL */\r
+}\r
+#endif\r
diff --git a/StdLib/LibC/String/strlcpy.c b/StdLib/LibC/String/strlcpy.c
new file mode 100644 (file)
index 0000000..5631e25
--- /dev/null
@@ -0,0 +1,82 @@
+/*  $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */\r
+/*  $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */\r
+\r
+/*\r
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL\r
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE\r
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\r
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\r
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r
+ */\r
+#include  <LibConfig.h>\r
+\r
+#if !defined(_KERNEL) && !defined(_STANDALONE)\r
+#if HAVE_NBTOOL_CONFIG_H\r
+#include "nbtool_config.h"\r
+#endif\r
+\r
+#include <sys/cdefs.h>\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+__RCSID("$NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $");\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#ifdef _LIBC\r
+#include "namespace.h"\r
+#endif\r
+#include <sys/types.h>\r
+#include <assert.h>\r
+#include <string.h>\r
+\r
+#ifdef _LIBC\r
+# ifdef __weak_alias\r
+__weak_alias(strlcpy, _strlcpy)\r
+# endif\r
+#endif\r
+#else\r
+#include <lib/libkern/libkern.h>\r
+#endif /* !_KERNEL && !_STANDALONE */\r
+\r
+\r
+#if !HAVE_STRLCPY\r
+/*\r
+ * Copy src to string dst of size siz.  At most siz-1 characters\r
+ * will be copied.  Always NUL terminates (unless siz == 0).\r
+ * Returns strlen(src); if retval >= siz, truncation occurred.\r
+ */\r
+size_t\r
+strlcpy(char *dst, const char *src, size_t siz)\r
+{\r
+  char *d = dst;\r
+  const char *s = src;\r
+  size_t n = siz;\r
+\r
+  _DIAGASSERT(dst != NULL);\r
+  _DIAGASSERT(src != NULL);\r
+\r
+  /* Copy as many bytes as will fit */\r
+  if (n != 0 && --n != 0) {\r
+    do {\r
+      if ((*d++ = *s++) == 0)\r
+        break;\r
+    } while (--n != 0);\r
+  }\r
+\r
+  /* Not enough room in dst, add NUL and traverse rest of src */\r
+  if (n == 0) {\r
+    if (siz != 0)\r
+      *d = '\0';    /* NUL-terminate dst */\r
+    while (*s++)\r
+      ;\r
+  }\r
+\r
+  return(s - src - 1);  /* count does not include NUL */\r
+}\r
+#endif\r
index 2519df94e49fac878a1b534d6fd6fb6d160be612..b3f6d0596555580562b6dda143b3c33620ba99ba 100644 (file)
@@ -40,7 +40,6 @@
        $NetBSD: strncasecmp.c,v 1.2 2007/06/04 18:19:27 christos Exp $\r
   strcasecmp.c 8.1 (Berkeley) 6/4/93\r
 **/\r
-\r
 #include <LibConfig.h>\r
 #include <sys/cdefs.h>\r
 \r
diff --git a/StdLib/LibC/String/strsep.c b/StdLib/LibC/String/strsep.c
new file mode 100644 (file)
index 0000000..234b0ca
--- /dev/null
@@ -0,0 +1,82 @@
+/*-\r
+ * Copyright (c) 1990, 1993\r
+ *  The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *  This product includes software developed by the University of\r
+ *  California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+#include  <LibConfig.h>\r
+\r
+#include <sys/cdefs.h>\r
+#include <string.h>\r
+#include <stdio.h>\r
+\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+static char sccsid[] = "@(#)strsep.c  8.1 (Berkeley) 6/4/93";\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+/*\r
+ * Get next token from string *stringp, where tokens are possibly-empty\r
+ * strings separated by characters from delim.\r
+ *\r
+ * Writes NULs into the string at *stringp to end tokens.\r
+ * delim need not remain constant from call to call.\r
+ * On return, *stringp points past the last NUL written (if there might\r
+ * be further tokens), or is NULL (if there are definitely no more tokens).\r
+ *\r
+ * If *stringp is NULL, strsep returns NULL.\r
+ */\r
+char *\r
+strsep(\r
+  register char **stringp,\r
+  register const char *delim\r
+  )\r
+{\r
+  register char *s;\r
+  register const char *spanp;\r
+  register int c, sc;\r
+  char *tok;\r
+\r
+  if ((s = *stringp) == NULL)\r
+    return (NULL);\r
+  for (tok = s;;) {\r
+    c = *s++;\r
+    spanp = delim;\r
+    do {\r
+      if ((sc = *spanp++) == c) {\r
+        if (c == 0)\r
+          s = NULL;\r
+        else\r
+          s[-1] = 0;\r
+        *stringp = s;\r
+        return (tok);\r
+      }\r
+    } while (sc != 0);\r
+  }\r
+  /* NOTREACHED */\r
+}\r
index 5cb93477526778a7ee395963fef841e7f75f5c0e..e3eccb593bae3cd144426d7239ecf44678fc83b7 100644 (file)
@@ -82,7 +82,6 @@ static void
 localsub(const time_t * const timep, const long   offset, struct tm * const tmp);\r
 \r
 clock_t\r
-EFIAPI\r
 __getCPS(void)\r
 {\r
   return gMD->ClocksPerSecond;\r
@@ -183,7 +182,7 @@ timesub(
 \r
 /** The clock function determines the processor time used.\r
 \r
-    @return   The clock function returns the implementation\92s best\r
+    @return   The clock function returns the implementation's best\r
               approximation to the processor time used by the program since the\r
               beginning of an implementation-defined era related only to the\r
               program invocation.  To determine the time in seconds, the value\r
@@ -196,7 +195,6 @@ timesub(
               CPU TimeStamp Counter ticks since the appliation started.\r
 **/\r
 clock_t\r
-EFIAPI\r
 clock(void)\r
 {\r
 #ifndef NT32dvm\r
@@ -213,7 +211,6 @@ clock(void)
 /**\r
 **/\r
 double\r
-EFIAPI\r
 difftime(time_t time1, time_t time0)\r
 {\r
   return (double)(time1 - time0);\r
@@ -429,7 +426,7 @@ time2sub(
   return t;\r
 }\r
 \r
-static time_t\r
+time_t\r
 time2(struct tm * const tmp, void (* const funcp)(const time_t*, long, struct tm*),\r
       const long offset, int * const okayp)\r
 {\r
@@ -542,7 +539,6 @@ time1(
               represented, the function returns the value (time_t)(-1).\r
 **/\r
 time_t\r
-EFIAPI\r
 mktime(struct tm *timeptr)\r
 {\r
   /* From NetBSD */\r
@@ -558,14 +554,13 @@ mktime(struct tm *timeptr)
 /** The time function determines the current calendar time.  The encoding of\r
     the value is unspecified.\r
 \r
-    @return   The time function returns the implementation\92s best approximation\r
+    @return   The time function returns the implementation's best approximation\r
               to the current calendar time.  The value (time_t)(-1) is returned\r
               if the calendar time is not available.  If timer is not a null\r
               pointer, the return value is also assigned to the object it\r
               points to.\r
 **/\r
 time_t\r
-EFIAPI\r
 time(time_t *timer)\r
 {\r
   time_t      CalTime;\r
@@ -633,7 +628,6 @@ time(time_t *timer)
     @return   The asctime function returns a pointer to the string.\r
 **/\r
 char *\r
-EFIAPI\r
 asctime(const struct tm *timeptr)\r
 {\r
   register const char * wn;\r
@@ -663,7 +657,6 @@ asctime(const struct tm *timeptr)
 /**\r
 **/\r
 char *\r
-EFIAPI\r
 ctime(const time_t *timer)\r
 {\r
   return asctime(localtime(timer));\r
@@ -672,7 +665,7 @@ ctime(const time_t *timer)
 /*\r
 ** gmtsub is to gmtime as localsub is to localtime.\r
 */\r
-static void\r
+void\r
 gmtsub(\r
   const time_t * const  timep,\r
   const long            offset,\r
@@ -718,7 +711,6 @@ gmtsub(
 /**\r
 **/\r
 struct tm *\r
-EFIAPI\r
 gmtime(const time_t *timer)\r
 {\r
   gmtsub(timer, 0L, &gMD->BDTime);\r
@@ -771,7 +763,6 @@ localsub(const time_t * const timep, const long   offset, struct tm * const tmp)
 /**\r
 **/\r
 struct tm *\r
-EFIAPI\r
 localtime(const time_t *timer)\r
 {\r
   tzset();\r
index 6de494f8d4c258e4816a45af8f9d4adf6dd18e28..3ad226951d6cf9c8d456cf74f4111ee6f8f0e9d6 100644 (file)
@@ -32,6 +32,8 @@
   strptime.c\r
   TimeEfi.c\r
   gettimeofday.c\r
+  timegm.c\r
+  itimer.c\r
 \r
 [Packages]\r
   StdLib/StdLib.dec\r
index 7b062c917b542915c3fd9ccf2b6f31fcf9e84772..8c033fd7d96bd64694934ca3969a66bb707a130d 100644 (file)
@@ -21,7 +21,6 @@
 \r
 /* Convert an EFI_TIME structure into a C Standard tm structure. */\r
 void\r
-EFIAPI\r
 Efi2Tm( EFI_TIME *ET, struct tm *BT)\r
 {\r
   // Convert EFI time to broken-down time.\r
@@ -39,7 +38,6 @@ Efi2Tm( EFI_TIME *ET, struct tm *BT)
 \r
 /* Convert an EFI_TIME structure into a time_t value. */\r
 time_t\r
-EFIAPI\r
 Efi2Time( EFI_TIME *EfiBDtime)\r
 {\r
   Efi2Tm( EfiBDtime, &gMD->BDTime);\r
index 72827f9a91d21b427d343f792243b0969303890c..f84f4f612a4a7c211aaf55bdddf2d0bbab70e1ad 100644 (file)
@@ -110,8 +110,8 @@ struct rule {
 #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */\r
 \r
 __BEGIN_DECLS\r
-extern void EFIAPI gmtload(struct state * const sp);\r
-extern void EFIAPI tzset(void);\r
+extern void gmtload(struct state * const sp);\r
+extern void tzset(void);\r
 __END_DECLS\r
 \r
 #endif  /* _TIMEVAL_H */\r
index e33b99ed6812e526e4ecffa254e0bf3ec24bf896..a7b589b7df720e933762d3a46b46c1741e70584d 100644 (file)
@@ -761,7 +761,6 @@ tzparse(
 }\r
 \r
 void\r
-EFIAPI\r
 gmtload(struct state * const sp)\r
 {\r
   if (tzload(gmt, sp) != 0)\r
@@ -788,7 +787,6 @@ tzsetwall(void)
 }\r
 \r
 void\r
-EFIAPI\r
 tzset(void)\r
 {\r
   register const char * name;\r
index 1c379a6b97678dd9afab7bda2e8aedbc376bb2c9..b26d15768453a23fe03ae038943daa56a81f79c8 100644 (file)
@@ -44,7 +44,6 @@
   Heimdal: gettimeofday.c 14773 2005-04-12 11:29:18Z lha $\r
   NetBSD: gettimeofday.c,v 1.2 2008/03/22 08:37:21 mlelstv Exp $\r
 **/\r
-\r
 #include <LibConfig.h>\r
 #include <sys/EfiCdefs.h>\r
 #include <sys/time.h>\r
diff --git a/StdLib/LibC/Time/itimer.c b/StdLib/LibC/Time/itimer.c
new file mode 100644 (file)
index 0000000..d6f6ab4
--- /dev/null
@@ -0,0 +1,277 @@
+/** @file \r
+  setitimer and getitimer functions.\r
+\r
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials are licensed and made available under\r
+  the terms and conditions of the BSD License that accompanies this distribution.\r
+  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+#include <LibConfig.h>\r
+#include <sys/EfiSysCall.h>\r
+#include <sys/time.h>\r
+#include <time.h>\r
+#include <errno.h>\r
+#include <sys/signal.h>\r
+#include <signal.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+STATIC EFI_EVENT RealTimer    = NULL;\r
+STATIC EFI_EVENT VirtualTimer = NULL;\r
+STATIC EFI_EVENT ProfTimer    = NULL;\r
+\r
+STATIC struct itimerval RealTimerInfo    = {{0,0},{0,0}};\r
+STATIC struct itimerval VirtualTimerInfo = {{0,0},{0,0}};\r
+STATIC struct itimerval ProfTimerInfo    = {{0,0},{0,0}};\r
+\r
+/**\r
+  Function to queue the next iteration of the timer.\r
+\r
+  This will copy the interval part of the struct into the value and (if \r
+  non-zero), then queue the next timer event.\r
+\r
+  @param[in] TimerInfo  The timer info structure.  \r
+  @param[in] Event      The EFI timer event.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetNext (\r
+  IN struct itimerval *TimerInfo,\r
+  IN EFI_EVENT        Event\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  CopyMem(&(TimerInfo->it_value), &(TimerInfo->it_interval), sizeof(struct timeval));\r
+\r
+  //\r
+  // If now zero then close and be done.\r
+  //\r
+  if (TimerInfo->it_value.tv_sec+TimerInfo->it_value.tv_usec == 0) {\r
+    if (Event != NULL) {\r
+      gBS->CloseEvent(Event);\r
+      Event = NULL;\r
+    }\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Set up for the next loop.\r
+  //\r
+  Status = gBS->SetTimer (\r
+    Event,\r
+    TimerRelative,\r
+    TimerInfo->it_value.tv_sec*10000000+TimerInfo->it_value.tv_usec*1000);\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    gBS->CloseEvent(Event);\r
+    Event = NULL;\r
+  }\r
+}\r
+\r
+/**\r
+  Notification function for real timer.\r
+\r
+  @param[in] Event    The event.\r
+  @param[in] Context  Ignored.\r
+**/\r
+VOID\r
+EFIAPI\r
+iTimerRealNotifyFunction (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  raise(SIGALRM);\r
+  SetNext(&RealTimerInfo, RealTimer);\r
+}\r
+\r
+/**\r
+  Notification function for virtual timer.\r
+\r
+  @param[in] Event    The event.\r
+  @param[in] Context  Ignored.\r
+**/\r
+VOID\r
+EFIAPI\r
+iTimerVirtualNotifyFunction (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  raise(SIGVTALRM);\r
+  SetNext(&VirtualTimerInfo, VirtualTimer);\r
+}\r
+\r
+/**\r
+  Notification function for prof timer.\r
+\r
+  @param[in] Event    The event.\r
+  @param[in] Context  Ignored.\r
+**/\r
+VOID\r
+EFIAPI\r
+iTimerProfNotifyFunction (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  raise(SIGPROF);\r
+  SetNext(&ProfTimerInfo, ProfTimer);\r
+}\r
+\r
+/**\r
+  The setitimer() function sets the timer specified by which to the value \r
+  specified in the structure pointed to by value, and if ovalue is not a null \r
+  pointer, stores the previous value of the timer in the structure pointed to\r
+  by ovalue. \r
+\r
+  A timer value is defined by the itimerval structure. If it_value is non-zero,\r
+  it indicates the time to the next timer expiration. If it_interval is \r
+  non-zero, it specifies a value to be used in reloading it_value when the \r
+  timer expires. Setting it_value to 0 disables a timer, regardless of the \r
+  value of it_interval. Setting it_interval to 0 disables a timer after its \r
+  next expiration (assuming it_value is non-zero). \r
+\r
+  ITIMER_REAL\r
+  Decrements in real time. A SIGALRM signal is delivered when this timer \r
+  expires. \r
+  \r
+  ITIMER_VIRTUAL\r
+  Decrements in process virtual time. It runs only when the process is \r
+  executing. A SIGVTALRM signal is delivered when it expires. \r
+\r
+  ITIMER_PROF\r
+  Decrements both in process virtual time and when the system is running on \r
+  behalf of the process. It is designed to be used by interpreters in \r
+  statistically profiling the execution of interpreted programs. Each time \r
+  the ITIMER_PROF timer expires, the SIGPROF signal is delivered. \r
+\r
+  @param[in] which      Which timer to set.  Possible values are described above.\r
+  @param[in] value      The new value for this timer.\r
+  @param[out] ovalue    The old value for this timer.\r
+\r
+  @retval 0 The operation was successful.\r
+  @retval -1 The operation failed. see errno for more details.\r
+**/\r
+\r
+int setitimer(\r
+  int which, \r
+  const struct itimerval *value,\r
+  struct itimerval *ovalue\r
+  )\r
+{\r
+  EFI_EVENT         *EventPointer;\r
+  EFI_EVENT_NOTIFY  NotifyFunction;\r
+  EFI_STATUS        Status;\r
+\r
+  if (value == NULL) {\r
+    errno = EINVAL;\r
+    return (-1);\r
+  }\r
+\r
+  if (which == ITIMER_REAL) {\r
+    EventPointer    = &RealTimer;\r
+    NotifyFunction  = iTimerRealNotifyFunction;\r
+    if (ovalue != NULL) {\r
+      CopyMem(ovalue, &RealTimerInfo, sizeof(struct itimerval));\r
+    }\r
+    CopyMem(&RealTimerInfo, value, sizeof(struct itimerval));\r
+  } else if (which == ITIMER_VIRTUAL) {\r
+    EventPointer    = &VirtualTimer;\r
+    NotifyFunction  = iTimerVirtualNotifyFunction;\r
+    if (ovalue != NULL) {\r
+      CopyMem(ovalue, &VirtualTimerInfo, sizeof(struct itimerval));\r
+    }\r
+    CopyMem(&VirtualTimerInfo, value, sizeof(struct itimerval));\r
+  } else if (which == ITIMER_PROF) {\r
+    EventPointer    = &ProfTimer;\r
+    NotifyFunction  = iTimerProfNotifyFunction;\r
+    if (ovalue != NULL) {\r
+      CopyMem(ovalue, &ProfTimerInfo, sizeof(struct itimerval));\r
+    }\r
+    CopyMem(&ProfTimerInfo, value, sizeof(struct itimerval));\r
+  } else {\r
+    errno = EINVAL;\r
+    return (-1);\r
+  }\r
+\r
+  if (*EventPointer != NULL) {\r
+    gBS->CloseEvent(*EventPointer);\r
+    *EventPointer = NULL;\r
+  }\r
+\r
+  //\r
+  // This was a 'please cancel me' request.\r
+  //\r
+  if (value->it_value.tv_sec+value->it_value.tv_usec == 0) {\r
+    return 0;\r
+  }\r
+\r
+  Status = gBS->CreateEvent (\r
+    EVT_TIMER|EVT_NOTIFY_SIGNAL,\r
+    EfiGetCurrentTpl(),\r
+    NotifyFunction,\r
+    NULL, // no context\r
+    EventPointer);\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    errno = EINVAL;\r
+    return (-1);\r
+  }\r
+\r
+  Status = gBS->SetTimer (\r
+    *EventPointer,\r
+    TimerRelative,\r
+    value->it_value.tv_sec*10000000+value->it_value.tv_usec*1000);\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    gBS->CloseEvent(*EventPointer);\r
+    *EventPointer = NULL;\r
+    errno = EINVAL;\r
+    return (-1);\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+/**\r
+  Function to get the current state of a timer.\r
+\r
+  @param[in] which    The identifier of the timer to get.  See setitimer for \r
+                      details.\r
+  @param[in] value    The pointer to populate.  must be pre-allocated to size.\r
+\r
+  @return 0           The operation was successful.\r
+  @return -1          The operation failed.  \r
+                      This means that value or which had an invalid value.\r
+**/\r
+int getitimer(\r
+  int which, \r
+  struct itimerval *value\r
+  )\r
+{\r
+\r
+  if (value == NULL) {\r
+    errno = EINVAL;\r
+    return (-1);\r
+  }\r
+\r
+  if (which == ITIMER_REAL) {\r
+      CopyMem(value, &RealTimerInfo, sizeof(struct itimerval));\r
+  } else if (which == ITIMER_VIRTUAL) {\r
+      CopyMem(value, &VirtualTimerInfo, sizeof(struct itimerval));\r
+  } else if (which == ITIMER_PROF) {\r
+      CopyMem(value, &ProfTimerInfo, sizeof(struct itimerval));\r
+  } else {\r
+    errno = EINVAL;\r
+    return (-1);\r
+  }\r
+\r
+  return 0;\r
+}
\ No newline at end of file
index 6a5e2a34af8c61210a508705a36fb8be5b57d500..11757b6129eed8314d23a5122918b0ddc1ed40bf 100644 (file)
@@ -72,9 +72,9 @@
 \r
 #define Locale  _CurrentTimeLocale\r
 \r
-static char * EFIAPI _add(const char *, char *, const char * const);\r
-static char * EFIAPI _conv(const int, const char * const, char * const, const char * const);\r
-static char * EFIAPI _fmt(const char *, const struct tm * const, char *, const char * const, int *);\r
+static char * _add(const char *, char *, const char * const);\r
+static char * _conv(const int, const char * const, char * const, const char * const);\r
+static char * _fmt(const char *, const struct tm * const, char *, const char * const, int *);\r
 \r
 #define NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU\r
 \r
@@ -89,7 +89,6 @@ static char * EFIAPI _fmt(const char *, const struct tm * const, char *, const c
 #define IN_ALL  3\r
 \r
 size_t\r
-EFIAPI\r
 strftime(\r
   char            * __restrict  s,\r
   size_t                        maxsize,\r
@@ -128,7 +127,6 @@ strftime(
 }\r
 \r
 static char *\r
-EFIAPI\r
 _fmt(\r
   const char      *       format,\r
   const struct tm * const t,\r
@@ -574,7 +572,6 @@ label:
 }\r
 \r
 static char *\r
-EFIAPI\r
 _conv(\r
   const int             n,\r
   const char  * const   format,\r
@@ -589,7 +586,6 @@ _conv(
 }\r
 \r
 static char *\r
-EFIAPI\r
 _add(\r
   const char  *       str,\r
   char        *       pt,\r
diff --git a/StdLib/LibC/Time/timegm.c b/StdLib/LibC/Time/timegm.c
new file mode 100644 (file)
index 0000000..a672dc8
--- /dev/null
@@ -0,0 +1,113 @@
+/** @file \r
+  timegm implementation\r
+\r
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials are licensed and made available under\r
+  the terms and conditions of the BSD License that accompanies this distribution.\r
+  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  * Copyright (c) 1987, 1989 Regents of the University of California.\r
+ * All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to Berkeley by\r
+ * Arthur David Olson of the National Cancer Institute.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *     This product includes software developed by the University of\r
+ *     California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+\r
+static char *sccsid = "from: @(#)ctime.c       5.26 (Berkeley) 2/23/91";\r
+\r
+\r
+ * This implementation of mktime is lifted straight from the NetBSD (BSD 4.4)\r
+ * version.  I modified it slightly to divorce it from the internals of the\r
+ * ctime library.  Thus this version can't use details of the internal\r
+ * timezone state file to figure out strange unnormalized struct tm values,\r
+ * as might result from someone doing date math on the tm struct then passing\r
+ * it to mktime.\r
+ *\r
+ * It just does as well as it can at normalizing the tm input, then does a\r
+ * binary search of the time space using the system's localtime() function.\r
+ *\r
+ * The original binary search was defective in that it didn't consider the\r
+ * setting of tm_isdst when comparing tm values, causing the search to be\r
+ * flubbed for times near the dst/standard time changeover.  The original\r
+ * code seems to make up for this by grubbing through the timezone info\r
+ * whenever the binary search barfed.  Since I don't have that luxury in\r
+ * portable code, I have to take care of tm_isdst in the comparison routine.\r
+ * This requires knowing how many minutes offset dst is from standard time.\r
+ *\r
+ * So, if you live somewhere in the world where dst is not 60 minutes offset,\r
+ * and your vendor doesn't supply mktime(), you'll have to edit this variable\r
+ * by hand.  Sorry about that.\r
+\r
+       $NetBSD: mktime.c,v 1.4 2006/06/11 19:34:10 kardel Exp $\r
+**/\r
+\r
+#include  <LibConfig.h>\r
+#include  <time.h>\r
+\r
+/*\r
+  This funciton is in Time.c, which has a different license than timegm.\r
+*/\r
+time_t \r
+time2(struct tm * const tmp, void (* const funcp)(const time_t*, long, struct tm*),\r
+      const long offset, int * const okayp);\r
+\r
+/*\r
+  This funciton is in Time.c, which has a different license than timegm.\r
+*/\r
+void\r
+gmtsub(\r
+  const time_t * const  timep,\r
+  const long            offset,\r
+  struct tm    * const  tmp\r
+  );\r
+\r
+#ifndef WRONG\r
+#define WRONG (-1)\r
+#endif /* !defined WRONG */\r
+\r
+/*\r
+  Convert a tm structure to a GMT based time_t.\r
+*/\r
+time_t timegm( struct tm * tmp )\r
+{\r
+       register time_t                 t;\r
+       int                             okay;\r
+\r
+       tmp->tm_isdst = 0;\r
+       t = time2(tmp, gmtsub, 0, &okay);\r
+       if (okay || tmp->tm_isdst < 0)\r
+               return t;\r
+\r
+       return WRONG;\r
+}
\ No newline at end of file
index c5799590813c22cb3d5b9158cacb0500bcec90ea..5dfc18acb49b9366c476f45ad9e8ce15f550cd59 100644 (file)
@@ -45,6 +45,12 @@ static const int stdioFlags[NUM_SPECIAL] = {
 static DeviceNode    *ConNode[NUM_SPECIAL];\r
 static ConInstance   *ConInstanceList;\r
 \r
+static wchar_t       *ConReadBuf;\r
+\r
+/* Flags settable by Ioctl */\r
+static BOOLEAN        TtyCooked;\r
+static BOOLEAN        TtyEcho;\r
+\r
 ssize_t\r
 WideTtyCvt( CHAR16 *dest, const char *buf, size_t n)\r
 {\r
@@ -127,74 +133,6 @@ da_ConSeek(
   }\r
 }\r
 \r
-static\r
-ssize_t\r
-EFIAPI\r
-da_ConRead(\r
-  IN OUT  struct __filedes   *filp,\r
-  IN OUT  off_t              *offset,         // Console ignores this\r
-  IN      size_t              BufferSize,\r
-     OUT  VOID               *Buffer\r
-)\r
-{\r
-  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *Proto;\r
-  ConInstance                      *Stream;\r
-  CHAR16                           *OutPtr;\r
-  EFI_INPUT_KEY                     Key;\r
-  UINTN                             NumChar;\r
-  UINTN                             Edex;\r
-  EFI_STATUS                        Status = RETURN_SUCCESS;\r
-  UINTN                             i;\r
-\r
-  Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
-  // Quick check to see if Stream looks reasonable\r
-  if(Stream->Cookie != CON_COOKIE) {    // Cookie == 'IoAb'\r
-    EFIerrno = RETURN_INVALID_PARAMETER;\r
-    return -1;    // Looks like a bad This pointer\r
-  }\r
-  if(Stream->InstanceNum != STDIN_FILENO) {\r
-    // Read only valid for stdin\r
-    EFIerrno = RETURN_UNSUPPORTED;\r
-    return -1;\r
-  }\r
-  // It looks like things are OK for trying to read\r
-  // We will accumulate *BufferSize characters or until we encounter\r
-  // an "activation" character.  Currently any control character.\r
-  Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;\r
-  OutPtr = Buffer;\r
-  NumChar = (BufferSize - 1) / sizeof(CHAR16);\r
-  i = 0;\r
-  do {\r
-    if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {\r
-      Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);\r
-      if(Status != RETURN_SUCCESS) {\r
-        break;\r
-      }\r
-      Status = Proto->ReadKeyStroke(Proto, &Key);\r
-      if(Status != RETURN_SUCCESS) {\r
-        break;\r
-      }\r
-    }\r
-    else {\r
-      Key.ScanCode          = Stream->UnGetKey.ScanCode;\r
-      Key.UnicodeChar       = Stream->UnGetKey.UnicodeChar;\r
-      Stream->UnGetKey.ScanCode     = SCAN_NULL;\r
-      Stream->UnGetKey.UnicodeChar  = CHAR_NULL;\r
-    }\r
-    if(Key.ScanCode == SCAN_NULL) {\r
-      *OutPtr++ = Key.UnicodeChar;\r
-      ++i;\r
-    }\r
-    if(iswcntrl(Key.UnicodeChar)) {    // If a control character, or a scan code\r
-      break;\r
-    }\r
-  } while(i < NumChar);\r
-\r
-  *OutPtr = L'\0';    // Terminate the input buffer\r
-  EFIerrno = Status;\r
-  return (ssize_t)(i * sizeof(CHAR16));  // Will be 0 if we didn't get a key\r
-}\r
-\r
 /* Write a NULL terminated WCS to the EFI console.\r
 \r
   @param[in,out]  BufferSize  Number of bytes in Buffer.  Set to zero if\r
@@ -265,6 +203,109 @@ da_ConWrite(
   return BufferSize;\r
 }\r
 \r
+/** Read characters from the console input device.\r
+\r
+    @param[in,out]  filp          Pointer to file descriptor for this file.\r
+    @param[in,out]  offset        Ignored.\r
+    @param[in]      BufferSize    Buffer size, in bytes.\r
+    @param[out]     Buffer        Buffer in which to place the read characters.\r
+\r
+    @return     Number of bytes actually placed into Buffer.\r
+\r
+    @todo       Handle encodings other than ASCII-7 and UEFI.\r
+**/\r
+static\r
+ssize_t\r
+EFIAPI\r
+da_ConRead(\r
+  IN OUT  struct __filedes   *filp,\r
+  IN OUT  off_t              *offset,         // Console ignores this\r
+  IN      size_t              BufferSize,\r
+     OUT  VOID               *Buffer\r
+)\r
+{\r
+  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *Proto;\r
+  ConInstance                      *Stream;\r
+  wchar_t                          *OutPtr;\r
+  EFI_INPUT_KEY                     Key;\r
+  UINTN                             NumChar;\r
+  UINTN                             Edex;\r
+  EFI_STATUS                        Status = RETURN_SUCCESS;\r
+  UINTN                             i;\r
+  char                              EchoBuff[MB_CUR_MAX + 1];\r
+  int                               NumEcho;\r
+\r
+  Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
+  // Quick check to see if Stream looks reasonable\r
+  if(Stream->Cookie != CON_COOKIE) {    // Cookie == 'IoAb'\r
+    EFIerrno = RETURN_INVALID_PARAMETER;\r
+    return -1;    // Looks like a bad This pointer\r
+  }\r
+  if(Stream->InstanceNum != STDIN_FILENO) {\r
+    // Read only valid for stdin\r
+    EFIerrno = RETURN_UNSUPPORTED;\r
+    return -1;\r
+  }\r
+  // It looks like things are OK for trying to read\r
+  // We will accumulate *BufferSize characters or until we encounter\r
+  // an "activation" character.  Currently any control character.\r
+  Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;\r
+  OutPtr = ConReadBuf;\r
+  NumChar = (BufferSize > MAX_INPUT)? MAX_INPUT : BufferSize;\r
+  i = 0;\r
+  do {\r
+    if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {\r
+      Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);\r
+      if(Status != RETURN_SUCCESS) {\r
+        break;\r
+      }\r
+      Status = Proto->ReadKeyStroke(Proto, &Key);\r
+      if(Status != RETURN_SUCCESS) {\r
+        break;\r
+      }\r
+    }\r
+    else {\r
+      Key.ScanCode          = Stream->UnGetKey.ScanCode;\r
+      Key.UnicodeChar       = Stream->UnGetKey.UnicodeChar;\r
+      Stream->UnGetKey.ScanCode     = SCAN_NULL;\r
+      Stream->UnGetKey.UnicodeChar  = CHAR_NULL;\r
+    }\r
+    if(Key.ScanCode == SCAN_NULL) {\r
+      NumEcho = 0;\r
+      if(TtyCooked && (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {\r
+        *OutPtr++ = CHAR_LINEFEED;\r
+        NumEcho = wctomb(EchoBuff, CHAR_LINEFEED);\r
+      }\r
+      else {\r
+        *OutPtr++ = Key.UnicodeChar;\r
+        NumEcho = wctomb(EchoBuff, Key.UnicodeChar);\r
+      }\r
+      ++i;\r
+      EchoBuff[NumEcho] = 0;  /* Terminate the Echo buffer */\r
+      if(TtyEcho) {\r
+        /* Echo the character just input */\r
+        da_ConWrite(&gMD->fdarray[STDOUT_FILENO], NULL, 2, EchoBuff);\r
+      }\r
+    }\r
+    if(iswcntrl(Key.UnicodeChar)) {    // If a control character, or a scan code\r
+      break;\r
+    }\r
+  } while(i < NumChar);\r
+\r
+  *OutPtr = L'\0';    // Terminate the input buffer\r
+\r
+  /*  Convert the input buffer and place in Buffer.\r
+      If the fully converted input buffer won't fit, write what will and\r
+      leave the rest in ConReadBuf with ConReadLeft indicating how many\r
+      unconverted characters remain in ConReadBuf.\r
+  */\r
+  NumEcho = (int)wcstombs(Buffer, ConReadBuf, BufferSize);   /* Re-use NumEcho to hold number of bytes in Buffer */\r
+  /* More work needs to be done before locales other than C can be supported. */\r
+\r
+  EFIerrno = Status;\r
+  return (ssize_t)NumEcho;  // Will be 0 if we didn't get a key\r
+}\r
+\r
 /** Console-specific helper function for the fstat() function.\r
 \r
     st_size       Set to number of characters read for stdin and number written for stdout and stderr.\r
@@ -347,27 +388,28 @@ da_ConIoctl(
 int\r
 EFIAPI\r
 da_ConOpen(\r
+  DeviceNode         *DevNode,\r
   struct __filedes   *filp,\r
-  void               *DevInstance,\r
+  int                 DevInstance,    // Not used for console devices\r
   wchar_t            *Path,           // Not used for console devices\r
-  wchar_t            *Flags           // Not used for console devices\r
+  wchar_t            *MPath           // Not used for console devices\r
   )\r
 {\r
   ConInstance                      *Stream;\r
 \r
   if((filp == NULL)           ||\r
-     (DevInstance  == NULL))\r
+     (DevNode  == NULL))\r
   {\r
     EFIerrno = RETURN_INVALID_PARAMETER;\r
     return -1;\r
   }\r
-  Stream = (ConInstance *)DevInstance;\r
+  Stream = (ConInstance *)DevNode->InstanceList;\r
   // Quick check to see if Stream looks reasonable\r
   if(Stream->Cookie != CON_COOKIE) {    // Cookie == 'IoAb'\r
     EFIerrno = RETURN_INVALID_PARAMETER;\r
     return -1;    // Looks like a bad This pointer\r
   }\r
-  gMD->StdIo[Stream->InstanceNum] = (ConInstance *)DevInstance;\r
+  gMD->StdIo[Stream->InstanceNum] = Stream;\r
   filp->f_iflags |= (S_IFREG | _S_IFCHR | _S_ICONSOLE);\r
   filp->f_offset = 0;\r
   filp->f_ops = &Stream->Abstraction;\r
@@ -448,7 +490,8 @@ __Cons_construct(
   int             i;\r
 \r
   ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance));\r
-  if(ConInstanceList == NULL) {\r
+  ConReadBuf      = (wchar_t *)AllocateZeroPool((MAX_INPUT + 1) * sizeof(wchar_t));\r
+  if((ConInstanceList == NULL) || (ConReadBuf == NULL))  {\r
     return RETURN_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -507,6 +550,10 @@ __Cons_construct(
     }\r
     Stream->Parent = ConNode[i];\r
   }\r
+  /* Initialize Ioctl flags until Ioctl is really implemented. */\r
+  TtyCooked = TRUE;\r
+  TtyEcho   = TRUE;\r
+\r
   return  Status;\r
 }\r
 \r
@@ -527,6 +574,9 @@ __Cons_deconstruct(
   if(ConInstanceList != NULL) {\r
     FreePool(ConInstanceList);\r
   }\r
+  if(ConReadBuf != NULL) {\r
+    FreePool(ConReadBuf);\r
+  }\r
 \r
   return RETURN_SUCCESS;\r
 }\r
index 37870e8384d07751dbd253933bd9c4b10f34695c..d56db49159d059c55c4f159052103da5135958ed 100644 (file)
@@ -29,6 +29,7 @@
 #include  <wctype.h>\r
 #include  <wchar.h>\r
 #include  <sys/fcntl.h>\r
+#include  <sys/syslimits.h>\r
 #include  <kfile.h>\r
 #include  <Device/Device.h>\r
 #include  <MainData.h>\r
@@ -321,7 +322,7 @@ da_ShellIoctl(
   void               *argp       ///< May be a pointer or a value\r
   )\r
 {\r
-  return 0;\r
+  return -EPERM;\r
 }\r
 \r
 /** Open an abstract Shell File.\r
@@ -329,10 +330,11 @@ da_ShellIoctl(
 int\r
 EFIAPI\r
 da_ShellOpen(\r
+  DeviceNode         *DevNode,\r
   struct __filedes   *filp,\r
-  void               *DevInstance,\r
+  int                 DevInstance,    /* Not used by Shell */\r
   wchar_t            *Path,\r
-  wchar_t            *Flags\r
+  wchar_t            *MPath\r
   )\r
 {\r
   UINT64                OpenMode;\r
@@ -340,8 +342,10 @@ da_ShellOpen(
   SHELL_FILE_HANDLE     FileHandle;\r
   GenericInstance      *Gip;\r
   char                 *NPath;\r
+  wchar_t              *WPath;\r
   RETURN_STATUS         Status;\r
   int                   oflags;\r
+  int                   retval;\r
 \r
   EFIerrno = RETURN_SUCCESS;\r
 \r
@@ -356,6 +360,23 @@ da_ShellOpen(
     return -1;\r
   }\r
 \r
+  /* Re-create the full mapped path for the shell. */\r
+  if(MPath != NULL) {\r
+    WPath = AllocateZeroPool(PATH_MAX * sizeof(wchar_t) + 1);\r
+    if(WPath == NULL) {\r
+      errno = ENOMEM;\r
+      EFIerrno = RETURN_OUT_OF_RESOURCES;\r
+      return -1;\r
+    }\r
+    wcsncpy(WPath, MPath, NAME_MAX);                /* Get the Map Name */\r
+    wcsncat(WPath, Path, (PATH_MAX - NAME_MAX));    /* Append the path */\r
+  }\r
+  else {\r
+    WPath = Path;\r
+  }\r
+\r
+  retval = -1;    /* Initially assume failure.  */\r
+\r
   /* Do we care if the file already exists?\r
      If O_TRUNC, then delete the file.  It will be created anew subsequently.\r
      If O_EXCL, then error if the file exists and O_CREAT is set.\r
@@ -363,23 +384,24 @@ da_ShellOpen(
   !!!!!!!!! Change this to use ShellSetFileInfo() to actually truncate the file\r
   !!!!!!!!! instead of deleting and re-creating it.\r
   */\r
+  do {  /* Do fake exception handling */\r
   if((oflags & O_TRUNC) || ((oflags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) {\r
-    Status = ShellIsFile( Path );\r
+      Status = ShellIsFile( WPath );\r
     if(Status == RETURN_SUCCESS) {\r
       // The file exists\r
       if(oflags & O_TRUNC) {\r
-        NPath = AllocateZeroPool(1024);\r
+          NPath = AllocateZeroPool(PATH_MAX);\r
         if(NPath == NULL) {\r
           errno = ENOMEM;\r
           EFIerrno = RETURN_OUT_OF_RESOURCES;\r
-          return -1;\r
+            break;\r
         }\r
-        wcstombs(NPath, Path, 1024);\r
+          wcstombs(NPath, WPath, PATH_MAX);\r
         // We do a truncate by deleting the existing file and creating a new one.\r
         if(unlink(NPath) != 0) {\r
           filp->f_iflags = 0;    // Release our reservation on this FD\r
           FreePool(NPath);\r
-          return -1;  // errno and EFIerrno are already set.\r
+            break;\r
         }\r
         FreePool(NPath);\r
       }\r
@@ -387,32 +409,40 @@ da_ShellOpen(
         errno = EEXIST;\r
         EFIerrno = RETURN_ACCESS_DENIED;\r
         filp->f_iflags = 0;    // Release our reservation on this FD\r
-        return -1;\r
+          break;\r
       }\r
     }\r
   }\r
 \r
   // Call the EFI Shell's Open function\r
-  Status = ShellOpenFileByName( Path, &FileHandle, OpenMode, Attributes);\r
+    Status = ShellOpenFileByName( WPath, &FileHandle, OpenMode, Attributes);\r
   if(RETURN_ERROR(Status)) {\r
     filp->f_iflags = 0;    // Release our reservation on this FD\r
     // Set errno based upon Status\r
     errno = EFI2errno(Status);\r
     EFIerrno = Status;\r
-    return -1;\r
+      break;\r
   }\r
+    retval = 0;\r
   // Successfully got a regular File\r
   filp->f_iflags |= S_IFREG;\r
 \r
   // Update the info in the fd\r
   filp->devdata = (void *)FileHandle;\r
 \r
-  Gip = (GenericInstance *)DevInstance;\r
+    Gip = (GenericInstance *)DevNode->InstanceList;\r
   filp->f_offset = 0;\r
   filp->f_ops = &Gip->Abstraction;\r
-//  filp->devdata = FileHandle;\r
+  //  filp->devdata = FileHandle;\r
+  } while(FALSE);\r
 \r
-  return 0;\r
+  /* If we get this far, WPath is not NULL.\r
+     If MPath is not NULL, then WPath was allocated so we need to free it.\r
+  */\r
+  if(MPath != NULL) {\r
+    FreePool(WPath);\r
+  }\r
+  return retval;\r
 }\r
 \r
 #include  <sys/poll.h>\r
@@ -468,9 +498,10 @@ da_ShellRename(
   RETURN_STATUS       Status;\r
   EFI_FILE_INFO      *NewFileInfo;\r
   EFI_FILE_INFO      *OldFileInfo;\r
-  char               *NewFn;\r
+  wchar_t            *NewFn;\r
   int                 OldFd;\r
   SHELL_FILE_HANDLE   FileHandle;\r
+  wchar_t            *NormalizedPath;\r
 \r
   // Open old file\r
   OldFd = open(from, O_RDWR, 0);\r
@@ -482,22 +513,20 @@ da_ShellRename(
       OldFileInfo = ShellGetFileInfo( FileHandle);\r
       if(OldFileInfo != NULL) {\r
         // Copy the Old file info into our new buffer, and free the old.\r
-        memcpy(OldFileInfo, NewFileInfo, sizeof(EFI_FILE_INFO));\r
+        memcpy(NewFileInfo, OldFileInfo, sizeof(EFI_FILE_INFO));\r
         FreePool(OldFileInfo);\r
+        // Normalize path and convert to WCS.\r
+        NormalizedPath = NormalizePath(to);\r
+        if (NormalizedPath != NULL) {\r
         // Strip off all but the file name portion of new\r
-        NewFn = strrchr(to, '/');\r
-        if(NewFn == NULL) {\r
-          NewFn = strrchr(to, '\\');\r
-          if(NewFn == NULL) {\r
-            NewFn = (char *)to;\r
-          }\r
-        }\r
-        // Convert new name from MBCS to WCS\r
-        (void)AsciiStrToUnicodeStr( NewFn, gMD->UString);\r
+          NewFn = GetFileNameFromPath(NormalizedPath);\r
         // Copy the new file name into our new file info buffer\r
-        wcsncpy(NewFileInfo->FileName, gMD->UString, wcslen(gMD->UString)+1);\r
+          wcsncpy(NewFileInfo->FileName, NewFn, wcslen(NewFn) + 1);\r
+          // Update the size of the structure.\r
+          NewFileInfo->Size = sizeof(EFI_FILE_INFO) + StrSize(NewFn);\r
         // Apply the new file name\r
         Status = ShellSetFileInfo(FileHandle, NewFileInfo);\r
+          free(NormalizedPath);\r
         free(NewFileInfo);\r
         if(Status == EFI_SUCCESS) {\r
           // File has been successfully renamed.  We are DONE!\r
@@ -507,6 +536,12 @@ da_ShellRename(
         EFIerrno = Status;\r
       }\r
       else {\r
+          free(NewFileInfo);\r
+          errno = ENOMEM;\r
+        }\r
+      }\r
+      else {\r
+        free(NewFileInfo);\r
         errno = EIO;\r
       }\r
     }\r
@@ -619,7 +654,7 @@ __ctor_DevShell(
   Stream->Abstraction.fo_poll     = &da_ShellPoll;\r
   Stream->Abstraction.fo_flush    = &fnullop_flush;\r
   Stream->Abstraction.fo_stat     = &da_ShellStat;\r
-  Stream->Abstraction.fo_ioctl    = &fbadop_ioctl;\r
+  Stream->Abstraction.fo_ioctl    = &da_ShellIoctl;\r
   Stream->Abstraction.fo_delete   = &da_ShellDelete;\r
   Stream->Abstraction.fo_rmdir    = &da_ShellRmdir;\r
   Stream->Abstraction.fo_mkdir    = &da_ShellMkdir;\r
index 2bdb33ac53bdb5e5b8d394b65d9894810e46e248..6510ce774783f83b59d6a44f0bfa65c9e0a33e21 100644 (file)
@@ -31,33 +31,33 @@ DeviceNode   *daCurrentDevice = NULL;     ///< Device currently being accessed
       fnullop_*   Does nothing and returns success.\r
       fbadop_*    Does nothing and returns EPERM\r
 */\r
-int     fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4)\r
+int     EFIAPI fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4)\r
 { return 0; }\r
 \r
-short  fnullop_poll  (struct __filedes *filp, short Events)\r
+short  EFIAPI fnullop_poll  (struct __filedes *filp, short Events)\r
 {\r
   return ((POLLIN | POLLRDNORM | POLLOUT) & Events);\r
 }\r
 \r
-int     fnullop_flush (struct __filedes *filp)\r
+int     EFIAPI fnullop_flush (struct __filedes *filp)\r
 { return 0; }\r
 \r
-int     fbadop_stat   (struct __filedes *filp, struct stat *StatBuf, void *Buf)\r
+int     EFIAPI fbadop_stat   (struct __filedes *filp, struct stat *StatBuf, void *Buf)\r
 { return -EPERM;  }\r
 \r
-int     fbadop_ioctl  (struct __filedes *filp, ULONGN Cmd, void *argp)\r
+int     EFIAPI fbadop_ioctl  (struct __filedes *filp, ULONGN Cmd, void *argp)\r
 { return -EPERM;  }\r
 \r
-int     fbadop_delete (struct __filedes *filp)\r
+int     EFIAPI fbadop_delete (struct __filedes *filp)\r
 { return -EPERM;  }\r
 \r
-int     fbadop_mkdir  (const char *path, __mode_t perms)\r
+int     EFIAPI fbadop_mkdir  (const char *path, __mode_t perms)\r
 { return -EPERM;  }\r
 \r
-int     fbadop_rename   (const char *from, const char *to)\r
+int     EFIAPI fbadop_rename   (const char *from, const char *to)\r
 { return -EPERM;  }\r
 \r
-int     fbadop_rmdir    (struct __filedes *filp)\r
+int     EFIAPI fbadop_rmdir    (struct __filedes *filp)\r
 { return -EPERM;  }\r
 \r
 /** Add a new device to the device list.\r
index 92bb1a20b77ed936a89ec147dd44c549a0143f0f..96392e018daccb599d2d60b6fb7f9e9ea2d467f7 100644 (file)
@@ -248,10 +248,16 @@ PathAlias(
 \r
 /** Parse a path producing the target device, device instance, and file path.\r
 \r
+    It is the caller's responsibility to free() FullPath and MapPath when they\r
+    are no longer needed.\r
+\r
     @param[in]    path\r
     @param[out]   FullPath\r
     @param[out]   DevNode\r
     @param[out]   Which\r
+    @param[out]   MapPath       OPTIONAL.  If not NULL, it points to the place to save a pointer\r
+                                to the extracted map name.  If the path didn't have a map name,\r
+                                then *MapPath is set to NULL.\r
 \r
     @retval   RETURN_SUCCESS              The path was parsed successfully.\r
     @retval   RETURN_NOT_FOUND            The path does not map to a valid device.\r
@@ -266,7 +272,8 @@ ParsePath(
   IN    const char   *path,\r
   OUT   wchar_t     **FullPath,\r
   OUT   DeviceNode  **DevNode,\r
-  OUT   int          *Which\r
+  OUT   int          *Which,\r
+  OUT   wchar_t     **MapPath\r
   )\r
 {\r
   int                 MapLen;\r
@@ -301,7 +308,7 @@ reclassify:
           // Get the Map Name, including the trailing ':'. */\r
           MPath = calloc(MapLen+2, sizeof(wchar_t));\r
           if(MPath != NULL) {\r
-            wmemcpy(MPath, WPath, MapLen+2);\r
+            wmemcpy(MPath, WPath, MapLen+1);\r
           }\r
           else {\r
             errno = ENOMEM;\r
@@ -346,6 +353,12 @@ reclassify:
   if(!RETURN_ERROR(Status)) {\r
     *FullPath = WPath;\r
     *Which    = Instance;\r
+    if(MapPath != NULL) {\r
+      *MapPath  = MPath;\r
+    }\r
+    else if(MPath != NULL) {\r
+      free(MPath);    /* Caller doesn't want it so let MPath go free */\r
+    }\r
 \r
     /*  At this point, WPath is an absolute path,\r
         MPath is either NULL or points to the Map Name,\r
@@ -359,6 +372,9 @@ reclassify:
       if(Node != NULL) {\r
         Status = RETURN_SUCCESS;\r
       }\r
+      else {\r
+        Status = RETURN_NOT_FOUND;\r
+      }\r
     }\r
     else {\r
       /* This is a mapped path. */\r
@@ -375,8 +391,41 @@ reclassify:
       *DevNode = Node;\r
     }\r
   }\r
-  if(MPath != NULL) {\r
-    free(MPath);    // We don't need this any more.\r
-  }\r
   return Status;\r
 }\r
+\r
+/**\r
+  Parses a normalized wide character path and returns a pointer to the entry\r
+  following the last \.  If a \ is not found in the path the return value will\r
+  be the same as the input value.  All error conditions return NULL.\r
+\r
+  The behavior when passing in a path that has not been normalized is undefined.\r
+\r
+  @param  Path - A pointer to a wide character string containing a path to a\r
+                 directory or a file.\r
+\r
+  @return Pointer to the file name or terminal directory.  NULL if an error is\r
+          detected.\r
+**/\r
+wchar_t *\r
+EFIAPI\r
+GetFileNameFromPath (\r
+  const wchar_t   *Path\r
+  )\r
+{\r
+  wchar_t   *Tail;\r
+\r
+  if (Path == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  Tail = wcsrchr(Path, L'\\');\r
+  if(Tail == NULL) {\r
+    Tail = (wchar_t *) Path;\r
+  } else {\r
+    // Move to the next character after the '\\' to get the file name.\r
+    Tail++;\r
+  }\r
+\r
+  return Tail;\r
+}\r
index 17865e4fecc1fd7d460738271e57f62fa2830bb4..802c6eb13cd25c2351db2c4e0d61f56a1399f6ca 100644 (file)
@@ -16,7 +16,7 @@
 [Defines]\r
   INF_VERSION                   = 0x00010005\r
   BASE_NAME                     = DevConsole\r
-  FILE_GUID                     = 42c078ef-14a8-4e30-9329-6f12d796e54a\r
+  FILE_GUID                     = f6937495-1f44-4a8a-8a1b-5a669f9396f6\r
   MODULE_TYPE                   = UEFI_APPLICATION\r
   VERSION_STRING                = 1.0\r
   LIBRARY_CLASS                 = DevConsole\r
 [Protocols]\r
   gEfiSimpleTextInProtocolGuid\r
   gEfiSimpleTextOutProtocolGuid\r
-\r
-################################################################\r
-#\r
-# The Build Options, below, are only used when building the C library.\r
-# DO NOT use them when building your application!\r
-# Nasty things could happen if you do.\r
-#\r
-# /Oi is required for Microsoft VC++ to allow "intrinsic" functions to be\r
-# defined in this library.\r
-#\r
-#[BuildOptions]\r
-#  MSFT:*_*_*_CC_FLAGS     = /Oi-\r
index 7b56f37363aa22dd5547597bdcfb20a60bff3848..56710259b6b11d40980b24291cefc17c6fa17d63 100644 (file)
@@ -19,7 +19,7 @@
 [Defines]\r
   INF_VERSION                   = 0x00010005\r
   BASE_NAME                     = DevShell\r
-  FILE_GUID                     = 42c078ef-14a8-4e30-9329-6f12d796e54a\r
+  FILE_GUID                     = 0a1d4fd8-4704-4501-85eb-93399492cbed\r
   MODULE_TYPE                   = UEFI_APPLICATION\r
   VERSION_STRING                = 1.0\r
   LIBRARY_CLASS                 = DevShell\r
   LibWchar\r
   LibUefi\r
   DevUtility\r
-\r
-################################################################\r
-#\r
-# The Build Options, below, are only used when building the C library.\r
-# DO NOT use them when building your application!\r
-# Nasty things could happen if you do.\r
-#\r
-# /Oi is required for Microsoft VC++ to allow "intrinsic" functions to be\r
-# defined in this library.\r
-#\r
-#[BuildOptions]\r
-#  MSFT:*_*_*_CC_FLAGS     = /Oi-\r
index 53daad28aca6b4ed4a0530daeb7ec45a132bc527..6bdc1eead9f8d7456cab406070fc94077349f2fe 100644 (file)
@@ -15,7 +15,7 @@
 [Defines]\r
   INF_VERSION                   = 0x00010005\r
   BASE_NAME                     = DevUtility\r
-  FILE_GUID                     = 42c078ef-14a8-4e30-9329-6f12d796e54a\r
+  FILE_GUID                     = d6a9928c-3397-4dd1-818f-c664ba6dcaaf\r
   MODULE_TYPE                   = UEFI_APPLICATION\r
   VERSION_STRING                = 1.0\r
   LIBRARY_CLASS                 = DevUtility\r
   LibC\r
   LibWchar\r
   LibUefi\r
-\r
-################################################################\r
-#\r
-# The Build Options, below, are only used when building the C library.\r
-# DO NOT use them when building your application!\r
-# Nasty things could happen if you do.\r
-#\r
-# /Oi- is required for Microsoft VC++ to allow "intrinsic" functions to be\r
-# defined in this library.\r
-#\r
-#[BuildOptions]\r
-#  MSFT:*_*_*_CC_FLAGS     = /Oi-\r
diff --git a/StdLib/LibC/Uefi/GetPass.c b/StdLib/LibC/Uefi/GetPass.c
new file mode 100644 (file)
index 0000000..9c0c1f4
--- /dev/null
@@ -0,0 +1,57 @@
+/** @file Implement the getpass function.\r
+\r
+  Copyright (c) 2011, Intel Corporation <BR>\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/ShellLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+static CHAR8   *ReturnStringAscii = NULL;\r
+\r
+char *getpass(const char *Prompt)\r
+{\r
+  BOOLEAN Ascii;\r
+  CHAR16  *ReturnString;\r
+\r
+  Ascii = FALSE;\r
+\r
+  Print(L"%a", Prompt);\r
+\r
+  ReturnString = ShellFileHandleReturnLine (gEfiShellParametersProtocol->StdIn, &Ascii);\r
+  if (ReturnString == NULL) {\r
+    return (NULL);\r
+  }\r
+\r
+  ReturnStringAscii = AllocateZeroPool((StrLen(ReturnString)+1)*sizeof(CHAR8));\r
+  if (ReturnStringAscii == NULL) {\r
+    return (NULL);\r
+  }\r
+\r
+  UnicodeStrToAsciiStr(ReturnString, ReturnStringAscii);\r
+\r
+  FreePool(ReturnString);\r
+\r
+  return (ReturnStringAscii);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DestructMePlease (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  SHELL_FREE_NON_NULL(ReturnStringAscii);\r
+\r
+  return EFI_SUCCESS;\r
+}
\ No newline at end of file
diff --git a/StdLib/LibC/Uefi/StubFunctions.c b/StdLib/LibC/Uefi/StubFunctions.c
new file mode 100644 (file)
index 0000000..da2eaf9
--- /dev/null
@@ -0,0 +1,79 @@
+/** @file\r
+  Implement the invalid functions to return failures.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include  <sys/EfiCdefs.h>\r
+#include  <sys/featuretest.h>\r
+#include  <namespace.h>\r
+#include  <stdio.h>\r
+#include  <pwd.h>\r
+#include  <errno.h>\r
+\r
+struct passwd *\r
+getpwuid (uid_t uid)\r
+{\r
+  uid;\r
+  errno = EPERM;\r
+  return NULL;\r
+}\r
+\r
+char *getlogin (void)\r
+{\r
+  errno = EPERM;\r
+  return NULL;\r
+}\r
+\r
+struct passwd *\r
+getpwnam (const char *name)\r
+{\r
+  name;\r
+  errno = EPERM;\r
+  return NULL;\r
+}\r
+\r
+uid_t getuid (void)\r
+{\r
+  return 0;\r
+}\r
+\r
+pid_t fork (void)\r
+{\r
+  errno = EPERM;\r
+  return (-1);\r
+}\r
+\r
+int chmod (const char *c, mode_t m)\r
+{\r
+  errno = EPERM;\r
+  return (-1);\r
+}\r
+\r
+pid_t   wait(int *stat_loc) {\r
+  return 0;\r
+}\r
+\r
+FILE *popen (const char *cmd, const char *type)\r
+{\r
+  errno = EPERM;\r
+  return NULL;\r
+}\r
+\r
+int pclose (FILE *stream)\r
+{\r
+  errno = EPERM;\r
+  return -1;\r
+}\r
+\r
+int access (const char *path, int amode)\r
+{\r
+  return 0;\r
+}\r
index b3ca5b89b4993ad958e525f76b37da1099d13b45..d2fb0c6af68fd84957231e835c2fe0103a6f28d7 100644 (file)
@@ -524,7 +524,7 @@ mkdir (const char *path, __mode_t perms)
   int                 Instance  = 0;\r
   int                 retval = 0;\r
 \r
-  Status = ParsePath(path, &NewPath, &Node, &Instance);\r
+  Status = ParsePath(path, &NewPath, &Node, &Instance, NULL);\r
   if(Status == RETURN_SUCCESS) {\r
     GenI = Node->InstanceList;\r
     if(GenI == NULL) {\r
@@ -532,7 +532,7 @@ mkdir (const char *path, __mode_t perms)
       retval  = -1;\r
       }\r
     else {\r
-      GenI += (Instance * Node->InstanceSize);\r
+      //GenI += (Instance * Node->InstanceSize);\r
       retval = ((GenericInstance *)GenI)->Abstraction.fo_mkdir( path, perms);\r
       }\r
     free(NewPath);\r
@@ -567,11 +567,15 @@ mkdir (const char *path, __mode_t perms)
     O_EXCL        -- if O_CREAT is also set, open will fail if the file already exists.\r
 **/\r
 int\r
-open   (const char *path, int oflags, int mode)\r
+open(\r
+  const char *path,\r
+  int oflags,\r
+  int mode\r
+  )\r
 {\r
   wchar_t              *NewPath;\r
+  wchar_t              *MPath;\r
   DeviceNode           *Node;\r
-  char                 *GenI = NULL;\r
   struct __filedes     *filp;\r
   int                   Instance  = 0;\r
   RETURN_STATUS         Status;\r
@@ -579,10 +583,10 @@ open   (const char *path, int oflags, int mode)
   int                   fd = -1;\r
   int                   doresult;\r
 \r
-  Status = ParsePath(path, &NewPath, &Node, &Instance);\r
+  Status = ParsePath(path, &NewPath, &Node, &Instance, &MPath);\r
   if(Status == RETURN_SUCCESS) {\r
-    if((Node != NULL)                       &&\r
-       ((GenI = Node->InstanceList) == NULL)) {\r
+    if((Node == NULL)               ||\r
+       (Node->InstanceList == NULL)) {\r
       errno   = EPERM;\r
   }\r
     else {\r
@@ -595,15 +599,14 @@ open   (const char *path, int oflags, int mode)
   if( fd < 0 ) {\r
     // All available FDs are in use\r
     errno = EMFILE;\r
-    return -1;\r
   }\r
+      else {\r
       filp = &gMD->fdarray[fd];\r
       // Save the flags and mode in the File Descriptor\r
       filp->Oflags = oflags;\r
       filp->Omode = mode;\r
 \r
-      GenI += (Instance * Node->InstanceSize);\r
-      doresult = Node->OpenFunc(filp, GenI, NewPath, NULL);\r
+        doresult = Node->OpenFunc(Node, filp, Instance, NewPath, MPath);\r
       if(doresult < 0) {\r
         filp->f_iflags = 0;   // Release this FD\r
         fd = -1;              // Indicate an error\r
@@ -618,8 +621,14 @@ open   (const char *path, int oflags, int mode)
         FILE_SET_MATURE(filp);\r
       }\r
           }\r
+    }\r
+    if(NewPath != NULL) {\r
     free(NewPath);\r
         }\r
+  }\r
+  if(MPath != NULL) {\r
+    free(MPath);    // We don't need this any more.\r
+  }\r
   // return the fd of our now open file\r
   return fd;\r
 }\r
@@ -748,6 +757,7 @@ poll (
     }\r
     } while (( 0 == SelectedFDs )\r
         && ( EFI_SUCCESS == Status ));\r
+\r
     //\r
     //  Stop the timer\r
     //\r
@@ -776,7 +786,6 @@ poll (
 }\r
 \r
 \r
-\r
 /** The rename() function changes the name of a file.\r
     The old argument points to the pathname of the file to be renamed. The new\r
     argument points to the new pathname of the file.\r
@@ -807,7 +816,6 @@ poll (
               shall be changed or created.\r
 **/\r
 int\r
-EFIAPI\r
 rename(\r
   const char *from,\r
   const char *to\r
@@ -820,7 +828,7 @@ rename(
   RETURN_STATUS       Status;\r
   int                 retval      = -1;\r
 \r
-  Status = ParsePath(from, &FromPath, &FromNode, &Instance);\r
+  Status = ParsePath(from, &FromPath, &FromNode, &Instance, NULL);\r
   if(Status == RETURN_SUCCESS) {\r
     GenI = FromNode->InstanceList;\r
     if(GenI == NULL) {\r
@@ -828,7 +836,7 @@ rename(
       retval  = -1;\r
       }\r
       else {\r
-      GenI += (Instance * FromNode->InstanceSize);\r
+      //GenI += (Instance * FromNode->InstanceSize);\r
       retval = ((GenericInstance *)GenI)->Abstraction.fo_rename( from, to);\r
               }\r
     free(FromPath);\r
@@ -839,7 +847,6 @@ rename(
 /**\r
 **/\r
 int\r
-EFIAPI\r
 rmdir(\r
   const char *path\r
   )\r
@@ -1006,13 +1013,13 @@ ioctl(
     from a file associated with a terminal may return one typed line of data.\r
 \r
     If fildes does not refer to a directory, the function reads the requested\r
-    number of bytes from the file at the file\92s current position and returns\r
+    number of bytes from the file at the file's current position and returns\r
     them in buf. If the read goes beyond the end of the file, the read\r
-    length is truncated to the end of the file. The file\92s current position is\r
+    length is truncated to the end of the file. The file's current position is\r
     increased by the number of bytes returned.\r
 \r
     If fildes refers to a directory, the function reads the directory entry at\r
-    the file\92s current position and returns the entry in buf. If buf\r
+    the file's current position and returns the entry in buf. If buf\r
     is not large enough to hold the current directory entry, then\r
     errno is set to EBUFSIZE, EFIerrno is set to EFI_BUFFER_TOO_SMALL, and the\r
     current file position is not updated. The size of the buffer needed to read\r
@@ -1129,3 +1136,56 @@ char
   \r
   return (UnicodeStrToAsciiStr(Cwd, buf));\r
 }\r
+\r
+/** Change the current working directory.\r
+\r
+  The chdir() function shall cause the directory named by the pathname\r
+  pointed to by the path argument to become the current working directory;\r
+  that is, the starting point for path searches for pathnames not beginning\r
+  with '/'.\r
+\r
+  @param[in] path   The new path to set.\r
+\r
+  @todo Add non-shell CWD changing.\r
+**/\r
+int\r
+chdir (const char *path)\r
+{\r
+  CONST CHAR16 *Cwd;\r
+  EFI_STATUS   Status;\r
+  CHAR16       *UnicodePath;\r
+\r
+  Cwd = ShellGetCurrentDir(NULL);\r
+  if (Cwd != NULL) {\r
+    /* We have shell support */\r
+    UnicodePath = AllocatePool(((AsciiStrLen (path) + 1) * sizeof (CHAR16)));\r
+    if (UnicodePath == NULL) {\r
+      errno = ENOMEM;\r
+      return -1;\r
+    }\r
+    AsciiStrToUnicodeStr(path, UnicodePath);\r
+    Status = gEfiShellProtocol->SetCurDir(NULL, UnicodePath);\r
+    FreePool(UnicodePath);\r
+    if (EFI_ERROR(Status)) {\r
+      errno = EACCES;\r
+      return -1;\r
+    } else {\r
+      return 0;\r
+    }\r
+  }\r
+\r
+  /* Add here for non-shell */\r
+  errno = EACCES;\r
+  return -1;\r
+}\r
+\r
+pid_t tcgetpgrp (int x)\r
+{\r
+  return ((pid_t)(UINTN)(gImageHandle));\r
+}\r
+\r
+pid_t getpgrp(void)\r
+{\r
+  return ((pid_t)(UINTN)(gImageHandle));\r
+}\r
+\r
index 084d6c4fc3dddc5b0870d29cf02370d0f7242a3e..30b619b409683860fe47f40a515fe1172b7d89ef 100644 (file)
 [Defines]\r
   INF_VERSION                    = 0x00010005\r
   BASE_NAME                      = LibUefi\r
-  FILE_GUID                      = 39356e02-26bf-4cfb-9564-378ce25e702f\r
+  FILE_GUID                      = 1dcff17c-aa53-4b78-b234-864027555035\r
   MODULE_TYPE                    = UEFI_APPLICATION\r
   VERSION_STRING                 = 1.0\r
   LIBRARY_CLASS                  = LibUefi\r
+  LIBRARY_CONSTRUCTOR            = DestructMePlease\r
 \r
 #\r
 #  VALID_ARCHITECTURES           = IA32 X64 IPF\r
 #\r
 \r
 [Sources]\r
+  select.c\r
   SysCalls.c\r
+  writev.c\r
   Xform.c\r
+  compat.c\r
+  GetPass.c\r
+  StubFunctions.c\r
 \r
 [Packages]\r
   StdLib/StdLib.dec\r
diff --git a/StdLib/LibC/Uefi/compat.c b/StdLib/LibC/Uefi/compat.c
new file mode 100644 (file)
index 0000000..7f250d1
--- /dev/null
@@ -0,0 +1,847 @@
+/*\r
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * $Id: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $\r
+\r
+ * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to The NetBSD Foundation\r
+ * by Klaus Klein and Jason R. Thorpe.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *        This product includes software developed by the NetBSD\r
+ *        Foundation, Inc. and its contributors.\r
+ * 4. Neither the name of The NetBSD Foundation nor the names of its\r
+ *    contributors may be used to endorse or promote products derived\r
+ *    from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\r
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ *  $NetBSD: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $\r
+\r
+ * Copyright (c) 1987, 1993\r
+ *  The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ *  $NetBSD: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $\r
+ */\r
+#include  <LibConfig.h>\r
+#include  <string.h>\r
+#include  <fcntl.h>\r
+\r
+#ifndef HAVE_GETOPT\r
+char *optarg;\r
+int optind = 1;\r
+int\r
+getopt(int argc, char **argv, char *args)\r
+{\r
+        size_t n;\r
+  size_t nlen = strlen(args);\r
+        char cmd;\r
+        char rv;\r
+\r
+        if (argv[optind] && *argv[optind] == '-') {\r
+                cmd = *(argv[optind] + 1);\r
+\r
+                for (n = 0; n < nlen; n++) {\r
+                        if (args[n] == ':')\r
+        continue;\r
+                        if (args[n] == cmd) {\r
+                                rv = *(argv[optind] + 1);\r
+                                if (args[n+1] == ':') {\r
+          if (*(argv[optind] + 2) != '\0') {\r
+                                          optarg = argv[optind] + 2;\r
+            optind += 1;\r
+          } else {\r
+                                          optarg = argv[optind + 1];\r
+                                          optind += 2;\r
+          }\r
+                                        if (!optarg)\r
+             optarg="";\r
+                                        return rv;\r
+                                } else {\r
+                                        optarg = NULL;\r
+                                        optind += 1;\r
+                                        return rv;\r
+                                }\r
+                        }\r
+                }\r
+        }\r
+\r
+        return -1;\r
+}\r
+#endif\r
+\r
+#ifdef WIN32\r
+#define ISPATHSEPARATOR(x) ((x == '/') || (x == '\\'))\r
+#else\r
+#define ISPATHSEPARATOR(x) (x == '/')\r
+#endif\r
+\r
+#ifndef HAVE_BASENAME\r
+#ifndef PATH_MAX\r
+#define PATH_MAX 5000\r
+#endif\r
+\r
+char *\r
+basename(char *path)\r
+{\r
+  static char singledot[] = ".";\r
+  static char result[PATH_MAX];\r
+  char *p, *lastp;\r
+  size_t len;\r
+\r
+  /*\r
+   * If `path' is a null pointer or points to an empty string,\r
+   * return a pointer to the string ".".\r
+   */\r
+  if ((path == NULL) || (*path == '\0'))\r
+    return (singledot);\r
+\r
+  /* Strip trailing slashes, if any. */\r
+  lastp = path + strlen(path) - 1;\r
+  while (lastp != path && ISPATHSEPARATOR(*lastp))\r
+    lastp--;\r
+\r
+  /* Now find the beginning of this (final) component. */\r
+  p = lastp;\r
+  while (p != path && !ISPATHSEPARATOR(*(p - 1)))\r
+    p--;\r
+\r
+  /* ...and copy the result into the result buffer. */\r
+  len = (lastp - p) + 1 /* last char */;\r
+  if (len > (PATH_MAX - 1))\r
+    len = PATH_MAX - 1;\r
+\r
+  memcpy(result, p, len);\r
+  result[len] = '\0';\r
+\r
+  return (result);\r
+}\r
+#endif\r
+\r
+#if !defined(HAVE_MKSTEMP) && !defined(WIN32)\r
+int\r
+mkstemp(char *path)\r
+{\r
+  char *start, *trv;\r
+  unsigned int pid;\r
+\r
+  /* To guarantee multiple calls generate unique names even if\r
+     the file is not created. 676 different possibilities with 7\r
+     or more X's, 26 with 6 or less. */\r
+  static char xtra[2] = "aa";\r
+  int xcnt = 0;\r
+\r
+  pid = getpid();\r
+\r
+  /* Move to end of path and count trailing X's. */\r
+  for (trv = path; *trv; ++trv)\r
+    if (*trv == 'X')\r
+      xcnt++;\r
+    else\r
+      xcnt = 0;\r
+\r
+  /* Use at least one from xtra.  Use 2 if more than 6 X's. */\r
+  if (*(trv - 1) == 'X')\r
+    *--trv = xtra[0];\r
+  if (xcnt > 6 && *(trv - 1) == 'X')\r
+    *--trv = xtra[1];\r
+\r
+  /* Set remaining X's to pid digits with 0's to the left. */\r
+  while (*--trv == 'X') {\r
+    *trv = (pid % 10) + '0';\r
+    pid /= 10;\r
+  }\r
+\r
+  /* update xtra for next call. */\r
+  if (xtra[0] != 'z')\r
+    xtra[0]++;\r
+  else {\r
+    xtra[0] = 'a';\r
+    if (xtra[1] != 'z')\r
+      xtra[1]++;\r
+    else\r
+      xtra[1] = 'a';\r
+  }\r
+\r
+  return open(path, O_CREAT | O_EXCL | O_RDWR, 0600);\r
+}\r
+#endif\r
+\r
+#ifndef HAVE_FFS\r
+int\r
+ffs(int x)\r
+{\r
+  int r = 1;\r
+  if (!x) return 0;\r
+  if (!(x & 0xffff)) { x >>= 16; r += 16; }\r
+  if (!(x &   0xff)) { x >>= 8;  r += 8;  }\r
+  if (!(x &    0xf)) { x >>= 4;  r += 4;  }\r
+  if (!(x &      3)) { x >>= 2;  r += 2;  }\r
+  if (!(x &      1)) { x >>= 1;  r += 1;  }\r
+\r
+  return r;\r
+}\r
+#endif\r
+\r
+/*\r
+ * Copyright Patrick Powell 1995\r
+ * This code is based on code written by Patrick Powell (papowell@astart.com)\r
+ * It may be used for any purpose as long as this notice remains intact\r
+ * on all source code distributions\r
+ */\r
+\r
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)\r
+\r
+static void\r
+dopr(char *buffer, size_t maxlen, const char *format, va_list args);\r
+\r
+static void\r
+fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags,\r
+    int min, int max);\r
+\r
+static void\r
+fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,\r
+    int min, int max, int flags);\r
+\r
+static void\r
+fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue,\r
+    int min, int max, int flags);\r
+\r
+static void\r
+dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);\r
+\r
+/*\r
+ * dopr(): poor man's version of doprintf\r
+ */\r
+\r
+/* format read states */\r
+#define DP_S_DEFAULT 0\r
+#define DP_S_FLAGS   1\r
+#define DP_S_MIN     2\r
+#define DP_S_DOT     3\r
+#define DP_S_MAX     4\r
+#define DP_S_MOD     5\r
+#define DP_S_CONV    6\r
+#define DP_S_DONE    7\r
+\r
+/* format flags - Bits */\r
+#define DP_F_MINUS  (1 << 0)\r
+#define DP_F_PLUS   (1 << 1)\r
+#define DP_F_SPACE  (1 << 2)\r
+#define DP_F_NUM    (1 << 3)\r
+#define DP_F_ZERO   (1 << 4)\r
+#define DP_F_UP     (1 << 5)\r
+#define DP_F_UNSIGNED   (1 << 6)\r
+\r
+/* Conversion Flags */\r
+#define DP_C_SHORT     1\r
+#define DP_C_LONG      2\r
+#define DP_C_LDOUBLE   3\r
+#define DP_C_LONG_LONG 4\r
+\r
+#define char_to_int(p) (p - '0')\r
+#define abs_val(p) (p < 0 ? -p : p)\r
+\r
+\r
+static void\r
+dopr(char *buffer, size_t maxlen, const char *format, va_list args)\r
+{\r
+  char *strvalue, ch;\r
+  long value;\r
+  long double fvalue;\r
+  int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0;\r
+  size_t currlen = 0;\r
+\r
+  ch = *format++;\r
+\r
+  while (state != DP_S_DONE) {\r
+    if ((ch == '\0') || (currlen >= maxlen))\r
+      state = DP_S_DONE;\r
+\r
+    switch(state) {\r
+    case DP_S_DEFAULT:\r
+      if (ch == '%')\r
+        state = DP_S_FLAGS;\r
+      else\r
+        dopr_outch(buffer, &currlen, maxlen, ch);\r
+      ch = *format++;\r
+      break;\r
+    case DP_S_FLAGS:\r
+      switch (ch) {\r
+      case '-':\r
+        flags |= DP_F_MINUS;\r
+        ch = *format++;\r
+        break;\r
+      case '+':\r
+        flags |= DP_F_PLUS;\r
+        ch = *format++;\r
+        break;\r
+      case ' ':\r
+        flags |= DP_F_SPACE;\r
+        ch = *format++;\r
+        break;\r
+      case '#':\r
+        flags |= DP_F_NUM;\r
+        ch = *format++;\r
+        break;\r
+      case '0':\r
+        flags |= DP_F_ZERO;\r
+        ch = *format++;\r
+        break;\r
+      default:\r
+        state = DP_S_MIN;\r
+        break;\r
+      }\r
+      break;\r
+    case DP_S_MIN:\r
+      if (isdigit((unsigned char)ch)) {\r
+        min = 10 * min + char_to_int (ch);\r
+        ch = *format++;\r
+      } else if (ch == '*') {\r
+        min = va_arg (args, int);\r
+        ch = *format++;\r
+        state = DP_S_DOT;\r
+      } else\r
+        state = DP_S_DOT;\r
+      break;\r
+    case DP_S_DOT:\r
+      if (ch == '.') {\r
+        state = DP_S_MAX;\r
+        ch = *format++;\r
+      } else\r
+        state = DP_S_MOD;\r
+      break;\r
+    case DP_S_MAX:\r
+      if (isdigit((unsigned char)ch)) {\r
+        if (max < 0)\r
+          max = 0;\r
+        max = 10 * max + char_to_int(ch);\r
+        ch = *format++;\r
+      } else if (ch == '*') {\r
+        max = va_arg (args, int);\r
+        ch = *format++;\r
+        state = DP_S_MOD;\r
+      } else\r
+        state = DP_S_MOD;\r
+      break;\r
+    case DP_S_MOD:\r
+      switch (ch) {\r
+      case 'h':\r
+        cflags = DP_C_SHORT;\r
+        ch = *format++;\r
+        break;\r
+      case 'l':\r
+        cflags = DP_C_LONG;\r
+        ch = *format++;\r
+        if (ch == 'l') {\r
+          cflags = DP_C_LONG_LONG;\r
+          ch = *format++;\r
+        }\r
+        break;\r
+      case 'q':\r
+        cflags = DP_C_LONG_LONG;\r
+        ch = *format++;\r
+        break;\r
+      case 'L':\r
+        cflags = DP_C_LDOUBLE;\r
+        ch = *format++;\r
+        break;\r
+      default:\r
+        break;\r
+      }\r
+      state = DP_S_CONV;\r
+      break;\r
+    case DP_S_CONV:\r
+      switch (ch) {\r
+      case 'd':\r
+      case 'i':\r
+        if (cflags == DP_C_SHORT)\r
+          value = va_arg(args, int);\r
+        else if (cflags == DP_C_LONG)\r
+          value = va_arg(args, long int);\r
+        else if (cflags == DP_C_LONG_LONG)\r
+          value = va_arg (args, long long);\r
+        else\r
+          value = va_arg (args, int);\r
+        fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);\r
+        break;\r
+      case 'o':\r
+        flags |= DP_F_UNSIGNED;\r
+        if (cflags == DP_C_SHORT)\r
+          value = va_arg(args, unsigned int);\r
+        else if (cflags == DP_C_LONG)\r
+          value = va_arg(args, unsigned long int);\r
+        else if (cflags == DP_C_LONG_LONG)\r
+          value = va_arg(args, unsigned long long);\r
+        else\r
+          value = va_arg(args, unsigned int);\r
+        fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);\r
+        break;\r
+      case 'u':\r
+        flags |= DP_F_UNSIGNED;\r
+        if (cflags == DP_C_SHORT)\r
+          value = va_arg(args, unsigned int);\r
+        else if (cflags == DP_C_LONG)\r
+          value = va_arg(args, unsigned long int);\r
+        else if (cflags == DP_C_LONG_LONG)\r
+          value = va_arg(args, unsigned long long);\r
+        else\r
+          value = va_arg(args, unsigned int);\r
+        fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);\r
+        break;\r
+      case 'X':\r
+        flags |= DP_F_UP;\r
+      case 'x':\r
+        flags |= DP_F_UNSIGNED;\r
+        if (cflags == DP_C_SHORT)\r
+          value = va_arg(args, unsigned int);\r
+        else if (cflags == DP_C_LONG)\r
+          value = va_arg(args, unsigned long int);\r
+        else if (cflags == DP_C_LONG_LONG)\r
+          value = va_arg(args, unsigned long long);\r
+        else\r
+          value = va_arg(args, unsigned int);\r
+        fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);\r
+        break;\r
+      case 'f':\r
+        if (cflags == DP_C_LDOUBLE)\r
+          fvalue = va_arg(args, long double);\r
+        else\r
+          fvalue = va_arg(args, double);\r
+        /* um, floating point? */\r
+        fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);\r
+        break;\r
+      case 'E':\r
+        flags |= DP_F_UP;\r
+      case 'e':\r
+        if (cflags == DP_C_LDOUBLE)\r
+          fvalue = va_arg(args, long double);\r
+        else\r
+          fvalue = va_arg(args, double);\r
+        break;\r
+      case 'G':\r
+        flags |= DP_F_UP;\r
+      case 'g':\r
+        if (cflags == DP_C_LDOUBLE)\r
+          fvalue = va_arg(args, long double);\r
+        else\r
+          fvalue = va_arg(args, double);\r
+        break;\r
+      case 'c':\r
+        dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));\r
+        break;\r
+      case 's':\r
+        strvalue = va_arg(args, char *);\r
+        if (max < 0)\r
+          max = maxlen; /* ie, no max */\r
+        fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);\r
+        break;\r
+      case 'p':\r
+        strvalue = va_arg(args, void *);\r
+        fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);\r
+        break;\r
+      case 'n':\r
+        if (cflags == DP_C_SHORT) {\r
+          short int *num;\r
+          num = va_arg(args, short int *);\r
+          *num = currlen;\r
+        } else if (cflags == DP_C_LONG) {\r
+          long int *num;\r
+          num = va_arg(args, long int *);\r
+          *num = currlen;\r
+        } else if (cflags == DP_C_LONG_LONG) {\r
+          long long *num;\r
+          num = va_arg(args, long long *);\r
+          *num = currlen;\r
+        } else {\r
+          int *num;\r
+          num = va_arg(args, int *);\r
+          *num = currlen;\r
+        }\r
+        break;\r
+      case '%':\r
+        dopr_outch(buffer, &currlen, maxlen, ch);\r
+        break;\r
+      case 'w': /* not supported yet, treat as next char */\r
+        ch = *format++;\r
+        break;\r
+      default: /* Unknown, skip */\r
+      break;\r
+      }\r
+      ch = *format++;\r
+      state = DP_S_DEFAULT;\r
+      flags = cflags = min = 0;\r
+      max = -1;\r
+      break;\r
+    case DP_S_DONE:\r
+      break;\r
+    default: /* hmm? */\r
+      break; /* some picky compilers need this */\r
+    }\r
+  }\r
+  if (currlen < maxlen - 1)\r
+    buffer[currlen] = '\0';\r
+  else\r
+    buffer[maxlen - 1] = '\0';\r
+}\r
+\r
+static void\r
+fmtstr(char *buffer, size_t *currlen, size_t maxlen,\r
+    char *value, int flags, int min, int max)\r
+{\r
+  int cnt = 0, padlen, strln;     /* amount to pad */\r
+\r
+  if (value == 0)\r
+    value = "<NULL>";\r
+\r
+  for (strln = 0; value[strln]; ++strln); /* strlen */\r
+  padlen = min - strln;\r
+  if (padlen < 0)\r
+    padlen = 0;\r
+  if (flags & DP_F_MINUS)\r
+    padlen = -padlen; /* Left Justify */\r
+\r
+  while ((padlen > 0) && (cnt < max)) {\r
+    dopr_outch(buffer, currlen, maxlen, ' ');\r
+    --padlen;\r
+    ++cnt;\r
+  }\r
+  while (*value && (cnt < max)) {\r
+    dopr_outch(buffer, currlen, maxlen, *value++);\r
+    ++cnt;\r
+  }\r
+  while ((padlen < 0) && (cnt < max)) {\r
+    dopr_outch(buffer, currlen, maxlen, ' ');\r
+    ++padlen;\r
+    ++cnt;\r
+  }\r
+}\r
+\r
+/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */\r
+\r
+static void\r
+fmtint(char *buffer, size_t *currlen, size_t maxlen,\r
+    long value, int base, int min, int max, int flags)\r
+{\r
+  unsigned long uvalue;\r
+  char convert[20];\r
+  int signvalue = 0, place = 0, caps = 0;\r
+  int spadlen = 0; /* amount to space pad */\r
+  int zpadlen = 0; /* amount to zero pad */\r
+\r
+#define PADMAX(x,y) ((x) > (y) ? (x) : (y))\r
+\r
+  if (max < 0)\r
+    max = 0;\r
+\r
+  uvalue = value;\r
+\r
+  if (!(flags & DP_F_UNSIGNED)) {\r
+    if (value < 0) {\r
+      signvalue = '-';\r
+      uvalue = -value;\r
+    } else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */\r
+      signvalue = '+';\r
+    else if (flags & DP_F_SPACE)\r
+      signvalue = ' ';\r
+  }\r
+\r
+  if (flags & DP_F_UP)\r
+    caps = 1; /* Should characters be upper case? */\r
+  do {\r
+    convert[place++] =\r
+        (caps ? "0123456789ABCDEF" : "0123456789abcdef")\r
+        [uvalue % (unsigned)base];\r
+    uvalue = (uvalue / (unsigned)base );\r
+  } while (uvalue && (place < 20));\r
+  if (place == 20)\r
+    place--;\r
+  convert[place] = 0;\r
+\r
+  zpadlen = max - place;\r
+  spadlen = min - PADMAX(max, place) - (signvalue ? 1 : 0);\r
+  if (zpadlen < 0)\r
+    zpadlen = 0;\r
+  if (spadlen < 0)\r
+    spadlen = 0;\r
+  if (flags & DP_F_ZERO) {\r
+    zpadlen = PADMAX(zpadlen, spadlen);\r
+    spadlen = 0;\r
+  }\r
+  if (flags & DP_F_MINUS)\r
+    spadlen = -spadlen; /* Left Justifty */\r
+\r
+  /* Spaces */\r
+  while (spadlen > 0) {\r
+    dopr_outch(buffer, currlen, maxlen, ' ');\r
+    --spadlen;\r
+  }\r
+\r
+  /* Sign */\r
+  if (signvalue)\r
+    dopr_outch(buffer, currlen, maxlen, signvalue);\r
+\r
+  /* Zeros */\r
+  if (zpadlen > 0) {\r
+    while (zpadlen > 0) {\r
+      dopr_outch(buffer, currlen, maxlen, '0');\r
+      --zpadlen;\r
+    }\r
+  }\r
+\r
+  /* Digits */\r
+  while (place > 0)\r
+    dopr_outch(buffer, currlen, maxlen, convert[--place]);\r
+\r
+  /* Left Justified spaces */\r
+  while (spadlen < 0) {\r
+    dopr_outch (buffer, currlen, maxlen, ' ');\r
+    ++spadlen;\r
+  }\r
+}\r
+\r
+static long double\r
+pow10(int exp)\r
+{\r
+  long double result = 1;\r
+\r
+  while (exp) {\r
+    result *= 10;\r
+    exp--;\r
+  }\r
+\r
+  return result;\r
+}\r
+\r
+static long\r
+round(long double value)\r
+{\r
+  long intpart = value;\r
+\r
+  value -= intpart;\r
+  if (value >= 0.5)\r
+    intpart++;\r
+\r
+  return intpart;\r
+}\r
+\r
+static void\r
+fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue,\r
+      int min, int max, int flags)\r
+{\r
+  char iconvert[20], fconvert[20];\r
+  int signvalue = 0, iplace = 0, fplace = 0;\r
+  int padlen = 0; /* amount to pad */\r
+  int zpadlen = 0, caps = 0;\r
+  long intpart, fracpart;\r
+  long double ufvalue;\r
+\r
+  /*\r
+   * AIX manpage says the default is 0, but Solaris says the default\r
+   * is 6, and sprintf on AIX defaults to 6\r
+   */\r
+  if (max < 0)\r
+    max = 6;\r
+\r
+  ufvalue = abs_val(fvalue);\r
+\r
+  if (fvalue < 0)\r
+    signvalue = '-';\r
+  else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */\r
+    signvalue = '+';\r
+  else if (flags & DP_F_SPACE)\r
+    signvalue = ' ';\r
+\r
+  intpart = ufvalue;\r
+\r
+  /*\r
+   * Sorry, we only support 9 digits past the decimal because of our\r
+   * conversion method\r
+   */\r
+  if (max > 9)\r
+    max = 9;\r
+\r
+  /* We "cheat" by converting the fractional part to integer by\r
+   * multiplying by a factor of 10\r
+   */\r
+  fracpart = round((pow10 (max)) * (ufvalue - intpart));\r
+\r
+  if (fracpart >= pow10 (max)) {\r
+    intpart++;\r
+    fracpart -= pow10 (max);\r
+  }\r
+\r
+  /* Convert integer part */\r
+  do {\r
+    iconvert[iplace++] =\r
+        (caps ? "0123456789ABCDEF" : "0123456789abcdef")\r
+        [intpart % 10];\r
+    intpart = (intpart / 10);\r
+  } while(intpart && (iplace < 20));\r
+  if (iplace == 20)\r
+    iplace--;\r
+  iconvert[iplace] = 0;\r
+\r
+  /* Convert fractional part */\r
+  do {\r
+    fconvert[fplace++] =\r
+        (caps ? "0123456789ABCDEF" : "0123456789abcdef")\r
+        [fracpart % 10];\r
+    fracpart = (fracpart / 10);\r
+  } while(fracpart && (fplace < 20));\r
+  if (fplace == 20)\r
+    fplace--;\r
+  fconvert[fplace] = 0;\r
+\r
+  /* -1 for decimal point, another -1 if we are printing a sign */\r
+  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);\r
+  zpadlen = max - fplace;\r
+  if (zpadlen < 0)\r
+    zpadlen = 0;\r
+  if (padlen < 0)\r
+    padlen = 0;\r
+  if (flags & DP_F_MINUS)\r
+    padlen = -padlen; /* Left Justifty */\r
+\r
+  if ((flags & DP_F_ZERO) && (padlen > 0)) {\r
+    if (signvalue) {\r
+      dopr_outch(buffer, currlen, maxlen, signvalue);\r
+      --padlen;\r
+      signvalue = 0;\r
+    }\r
+    while (padlen > 0) {\r
+      dopr_outch(buffer, currlen, maxlen, '0');\r
+      --padlen;\r
+    }\r
+  }\r
+  while (padlen > 0) {\r
+    dopr_outch(buffer, currlen, maxlen, ' ');\r
+    --padlen;\r
+  }\r
+  if (signvalue)\r
+    dopr_outch(buffer, currlen, maxlen, signvalue);\r
+\r
+  while (iplace > 0)\r
+    dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);\r
+\r
+  /*\r
+   * Decimal point.  This should probably use locale to find the\r
+   * correct char to print out.\r
+   */\r
+  dopr_outch(buffer, currlen, maxlen, '.');\r
+\r
+  while (fplace > 0)\r
+    dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);\r
+\r
+  while (zpadlen > 0) {\r
+    dopr_outch(buffer, currlen, maxlen, '0');\r
+    --zpadlen;\r
+  }\r
+\r
+  while (padlen < 0) {\r
+    dopr_outch(buffer, currlen, maxlen, ' ');\r
+    ++padlen;\r
+  }\r
+}\r
+\r
+static void\r
+dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)\r
+{\r
+  if (*currlen < maxlen)\r
+    buffer[(*currlen)++] = c;\r
+}\r
+#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */\r
+\r
+#ifndef HAVE_VSNPRINTF\r
+int\r
+vsnprintf(char *str, size_t count, const char *fmt, va_list args)\r
+{\r
+  str[0] = 0;\r
+  dopr(str, count, fmt, args);\r
+\r
+  return(strlen(str));\r
+}\r
+#endif /* !HAVE_VSNPRINTF */\r
+\r
+#ifndef HAVE_SNPRINTF\r
+int\r
+snprintf(char *str,size_t count,const char *fmt,...)\r
+{\r
+  va_list ap;\r
+\r
+  va_start(ap, fmt);\r
+  (void) vsnprintf(str, count, fmt, ap);\r
+  va_end(ap);\r
+\r
+  return(strlen(str));\r
+}\r
+\r
+#endif /* !HAVE_SNPRINTF */\r
diff --git a/StdLib/LibC/Uefi/select.c b/StdLib/LibC/Uefi/select.c
new file mode 100644 (file)
index 0000000..8da03e6
--- /dev/null
@@ -0,0 +1,256 @@
+/*\r
+ * Copyright (c) 1982, 1986, 1989, 1993\r
+ *  The Regents of the University of California.  All rights reserved.\r
+ * (c) UNIX System Laboratories, Inc.\r
+ * All or some portions of this file are derived from material licensed\r
+ * to the University of California by American Telephone and Telegraph\r
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with\r
+ * the permission of UNIX System Laboratories, Inc.\r
+ *\r
+ * Portions copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by the University of\r
+ *    California, Berkeley, Intel Corporation, and its contributors.\r
+ *\r
+ * 4. Neither the name of University, Intel Corporation, or their respective\r
+ *    contributors may be used to endorse or promote products derived from\r
+ *    this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND\r
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,\r
+ * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ *  @(#)sys_generic.c 8.5 (Berkeley) 1/21/94\r
+ * $Id: select.c,v 1.1.1.1 2003/11/19 01:50:30 kyu3 Exp $\r
+ */\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include  <LibConfig.h>\r
+\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+#include <sys/poll.h>\r
+#include <sys/param.h>\r
+#include <sys/time.h>\r
+#include  <extern.h>      /* For ffs() */\r
+#ifndef KERNEL\r
+#define KERNEL\r
+#include <errno.h>\r
+#undef KERNEL\r
+#else\r
+#include <errno.h>\r
+#endif\r
+\r
+#ifdef  EFI_NT_EMULATOR\r
+#define _SELECT_DELAY_  10000\r
+#else\r
+#define _SELECT_DELAY_  1000\r
+#endif\r
+\r
+#define MAX_SLEEP_DELAY 0xfffffffe\r
+\r
+//\r
+//  Name:\r
+//      usleep\r
+//\r
+//  Description:\r
+//      Implement usleep(3) function.\r
+//\r
+//  Arguments:\r
+//      Microseconds to sleep.\r
+//\r
+//  Returns:\r
+//      0\r
+//\r
+int\r
+usleep( useconds_t Microseconds )\r
+{\r
+  while ( MAX_SLEEP_DELAY < Microseconds ) {\r
+    gBS->Stall ( MAX_SLEEP_DELAY );\r
+    Microseconds -= MAX_SLEEP_DELAY;\r
+  }\r
+  gBS->Stall((UINTN)Microseconds );\r
+  return (0);\r
+}\r
+\r
+static int\r
+selscan(\r
+  fd_mask **ibits,\r
+  fd_mask **obits,\r
+  int nfd,\r
+  int *nselected\r
+  )\r
+{\r
+  int   msk;\r
+  int i;\r
+  int j;\r
+  int fd;\r
+  int n;\r
+  struct pollfd pfd;\r
+  int FdCount;\r
+  fd_mask   bits;\r
+  /* Note: backend also returns POLLHUP/POLLERR if appropriate. */\r
+  static int16_t  flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND };\r
+\r
+  for (msk = 0, n = 0; msk < 3; msk++) {\r
+    if (ibits[msk] == NULL)\r
+      continue;\r
+    for (i = 0; i < nfd; i += NFDBITS) {\r
+      bits = ibits[ msk ][ i / NFDBITS ];\r
+      while (( 0 != (j = ffs(bits))) && ((fd = i + --j) < nfd)) {\r
+        bits &= ~(1 << j);\r
+\r
+        pfd.fd = fd;\r
+        pfd.events = flag[msk];\r
+        pfd.revents = 0;\r
+        FdCount = poll ( &pfd, 1, 0 );\r
+        if ( -1 == FdCount ) {\r
+          return errno;\r
+        }\r
+        if ( 0 != FdCount ) {\r
+          obits[msk][(fd)/NFDBITS] |=\r
+            (1 << ((fd) % NFDBITS));\r
+          n++;\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  *nselected = n;\r
+  return (0);\r
+}\r
+\r
+int\r
+select(\r
+  int nd,\r
+  fd_set  *in,\r
+  fd_set *ou,\r
+  fd_set *ex,\r
+  struct  timeval *tv\r
+  )\r
+{\r
+  fd_mask *ibits[3], *obits[3], *selbits, *sbp;\r
+  int error, forever, nselected;\r
+  u_int nbufbytes, ncpbytes, nfdbits;\r
+  int64_t timo;\r
+\r
+  if (nd < 0)\r
+    return (EINVAL);\r
+\r
+  /*\r
+   * Allocate just enough bits for the non-null fd_sets.  Use the\r
+   * preallocated auto buffer if possible.\r
+   */\r
+  nfdbits = roundup(nd, NFDBITS);\r
+  ncpbytes = nfdbits / NBBY;\r
+  nbufbytes = 0;\r
+  if (in != NULL)\r
+    nbufbytes += 2 * ncpbytes;\r
+  if (ou != NULL)\r
+    nbufbytes += 2 * ncpbytes;\r
+  if (ex != NULL)\r
+    nbufbytes += 2 * ncpbytes;\r
+  selbits = malloc(nbufbytes);\r
+\r
+  /*\r
+   * Assign pointers into the bit buffers and fetch the input bits.\r
+   * Put the output buffers together so that they can be bzeroed\r
+   * together.\r
+   */\r
+  sbp = selbits;\r
+#define getbits(name, x) \\r
+  do {                \\r
+    if (name == NULL)         \\r
+      ibits[x] = NULL;        \\r
+    else {              \\r
+      ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \\r
+      obits[x] = sbp;         \\r
+      sbp += ncpbytes / sizeof *sbp;      \\r
+      bcopy(name, ibits[x], ncpbytes);    \\r
+    }             \\r
+  } while (0)\r
+  getbits(in, 0);\r
+  getbits(ou, 1);\r
+  getbits(ex, 2);\r
+#undef  getbits\r
+  if (nbufbytes != 0)\r
+    memset(selbits, 0, nbufbytes / 2);\r
+\r
+  if (tv) {\r
+    timo = tv->tv_usec + (tv->tv_sec * 1000000);\r
+    forever = 0;\r
+  } else {\r
+    timo = 0;\r
+    forever = 1;\r
+  }\r
+\r
+  /*\r
+   *  Poll for I/O events\r
+   */\r
+  nselected = 0;\r
+  do {\r
+    /*\r
+     *  Scan for pending I/O\r
+     */\r
+    error = selscan(ibits, obits, nd, &nselected);\r
+    if (error || nselected)\r
+      break;\r
+\r
+    /*\r
+     *  Adjust timeout is needed\r
+     */\r
+    if (timo)  {\r
+      /*\r
+       *  Give it a rest\r
+       */\r
+      usleep( _SELECT_DELAY_ );\r
+      timo -= _SELECT_DELAY_;\r
+    }\r
+\r
+  } while (timo > 0 || forever);\r
+\r
+  /* select is not restarted after signals... */\r
+  if (error == ERESTART)\r
+    error = EINTR;\r
+  else if (error == EWOULDBLOCK)\r
+    error = 0;\r
+\r
+#define putbits(name, x)  if (name) bcopy(obits[x], name, ncpbytes)\r
+  if (error == 0) {\r
+    putbits(in, 0);\r
+    putbits(ou, 1);\r
+    putbits(ex, 2);\r
+#undef putbits\r
+  } else {\r
+    errno = error;\r
+    nselected = -1;\r
+  }\r
+\r
+  free( selbits );\r
+  return ( nselected );\r
+}\r
diff --git a/StdLib/LibC/Uefi/writev.c b/StdLib/LibC/Uefi/writev.c
new file mode 100644 (file)
index 0000000..9cff086
--- /dev/null
@@ -0,0 +1,143 @@
+/*\r
+ * Copyright (c) 1999, 2000\r
+ * Intel Corporation.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ *    this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ *    this list of conditions and the following disclaimer in the documentation\r
+ *    and/or other materials provided with the distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this software must\r
+ *    display the following acknowledgement:\r
+ *\r
+ *    This product includes software developed by Intel Corporation and its\r
+ *    contributors.\r
+ *\r
+ * 4. Neither the name of Intel Corporation or its contributors may be used to\r
+ *    endorse or promote products derived from this software without specific\r
+ *    prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR\r
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ */\r
+\r
+/*++\r
+\r
+Module Name:\r
+\r
+    writev.c\r
+\r
+Abstract:\r
+\r
+    Functions implementing the standard "writev" system call interface\r
+\r
+\r
+Revision History\r
+\r
+--*/\r
+#include  <LibConfig.h>\r
+\r
+#ifdef foo\r
+#include <efi_interface.h>\r
+#include <unistd.h>\r
+#include <fcntl.h>\r
+#define KERNEL\r
+#include <errno.h>\r
+#undef KERNEL\r
+#include "./filedesc.h"\r
+\r
+#include <libc_debug.h>\r
+#include <assert.h>\r
+#endif\r
+\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <sys/uio.h>\r
+#include <string.h>\r
+#ifndef KERNEL\r
+#define KERNEL\r
+#include <errno.h>\r
+#undef KERNEL\r
+#else\r
+#include <errno.h>\r
+#endif\r
+\r
+//\r
+//  Name:\r
+//      writev\r
+//\r
+//  Description:\r
+//      BSD writev interface for libc\r
+//\r
+//  Arguments:\r
+//      File Descriptor (index into file descriptor table)\r
+//      iovec pointer\r
+//      size of iovec array\r
+//\r
+//  Returns:\r
+//      number of bytes written\r
+//\r
+\r
+ssize_t\r
+writev(\r
+    int fd,\r
+    const struct iovec *iov,\r
+    int iovcnt\r
+    )\r
+{\r
+  const struct iovec  *pVecTmp;\r
+  char      *pBuf, *pBufTmp;\r
+  size_t      TotalBytes, i, ret;\r
+\r
+  //\r
+  //  See how much memory we'll need\r
+  //\r
+\r
+  for (i = 0, TotalBytes = 0, pVecTmp = iov; i < (size_t)iovcnt; i++, pVecTmp++) {\r
+    TotalBytes += pVecTmp->iov_len;\r
+  }\r
+\r
+  //\r
+  //  Allocate a contiguous buffer\r
+  //\r
+\r
+  pBuf = (char*)malloc (TotalBytes);\r
+  if (pBuf == NULL) {\r
+    errno = ENOMEM;\r
+    return -1;\r
+  }\r
+\r
+  //\r
+  //  Copy vectors to the buffer\r
+  //\r
+\r
+  for (pBufTmp = pBuf; iovcnt; iovcnt--) {\r
+    bcopy(iov->iov_base, pBuf, iov->iov_len);\r
+    pBuf += iov->iov_len;\r
+    iov++;\r
+  }\r
+\r
+  //\r
+  //  Use standard write(2) then free buffer\r
+  //\r
+\r
+  ret = write (fd, pBuf, TotalBytes);\r
+  free (pBuf);\r
+\r
+  return (ret);\r
+}\r
diff --git a/StdLib/PosixLib/Err/LibErr.inf b/StdLib/PosixLib/Err/LibErr.inf
new file mode 100644 (file)
index 0000000..fe1b5d4
--- /dev/null
@@ -0,0 +1,42 @@
+##  @file\r
+#   Library used for supplying some POSIX routines.\r
+#\r
+#  Copyright (c) 2011, Intel Corporation. All rights reserved. <BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = LibErr\r
+  FILE_GUID                      = FC1D4706-88FB-42b0-98B0-A4B2E607EBAA\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = LibErr|UEFI_APPLICATION UEFI_DRIVER\r
+\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  warn_err.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  StdLib/StdLib.dec\r
+  StdLibPrivateInternalFiles/DoNotUse.dec\r
+\r
+[Libraries]\r
+  LibC\r
+  LibStdio\r
+  LibStdLib\r
+  LibString\r
diff --git a/StdLib/PosixLib/Err/warn_err.c b/StdLib/PosixLib/Err/warn_err.c
new file mode 100644 (file)
index 0000000..b69a417
--- /dev/null
@@ -0,0 +1,99 @@
+/** @file\r
+  Implement the warning and error output messages.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ * Copyright (c) 1994 Michael L. Hitch\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ *    must display the following acknowledgement:\r
+ *      This product includes software developed by Michael L. Hitch.\r
+ * 4. The name of the author may not be used to endorse or promote products\r
+ *    derived from this software without specific prior written permission\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ **/\r
+#include  <LibConfig.h>\r
+\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <errno.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+static void\r
+_Vdomessage(int doerrno, const char *fmt, va_list args)\r
+{\r
+  fprintf(stderr, "%s: ", getprogname());\r
+  if (fmt) {\r
+    vfprintf(stderr, fmt, args);\r
+    fprintf(stderr, ": ");\r
+  }\r
+  if (doerrno && errno < EMAXERRORVAL) {\r
+    fprintf(stderr, "%s", strerror(errno));\r
+  }\r
+  fprintf(stderr, "\n");\r
+}\r
+\r
+void\r
+err(int eval, const char *fmt, ...)\r
+{\r
+  va_list ap;\r
+  va_start(ap, fmt);\r
+  _Vdomessage(1, fmt, ap);\r
+  va_end(ap);\r
+  exit(eval);\r
+}\r
+\r
+void\r
+errx(int eval, const char *fmt, ...)\r
+{\r
+  va_list ap;\r
+  va_start(ap, fmt);\r
+  _Vdomessage(0, fmt, ap);\r
+  va_end(ap);\r
+  exit(eval);\r
+}\r
+\r
+void\r
+warn(const char *fmt, ...)\r
+{\r
+  va_list ap;\r
+  va_start(ap, fmt);\r
+  _Vdomessage(1, fmt, ap);\r
+  va_end(ap);\r
+}\r
+\r
+void\r
+warnx(const char *fmt, ...)\r
+{\r
+  va_list ap;\r
+  va_start(ap, fmt);\r
+  _Vdomessage(0, fmt, ap);\r
+  va_end(ap);\r
+}\r
diff --git a/StdLib/PosixLib/Gen/LibGen.inf b/StdLib/PosixLib/Gen/LibGen.inf
new file mode 100644 (file)
index 0000000..276b2ee
--- /dev/null
@@ -0,0 +1,41 @@
+##  @file\r
+#   Library used for supplying glob POSIX routines.\r
+#\r
+#  Copyright (c) 2011, Intel Corporation. All rights reserved. <BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = LibGen\r
+  FILE_GUID                      = CA599759-90A7-4fe4-BC8B-4B71C350DCAC\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = LibGen|UEFI_APPLICATION UEFI_DRIVER\r
+\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  dirname.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  StdLib/StdLib.dec\r
+  StdLibPrivateInternalFiles/DoNotUse.dec\r
+\r
+[Libraries]\r
+  LibString\r
+  LibStdLib\r
+\r
+[Pcd]\r
diff --git a/StdLib/PosixLib/Gen/dirname.c b/StdLib/PosixLib/Gen/dirname.c
new file mode 100644 (file)
index 0000000..7fb4d39
--- /dev/null
@@ -0,0 +1,88 @@
+/** @file\r
+\r
+ * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to The NetBSD Foundation\r
+ * by Klaus Klein and Jason R. Thorpe.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\r
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+\r
+    NetBSD: dirname.c,v 1.10 2008/05/10 22:39:40 christos Exp\r
+ */\r
+#include  <LibConfig.h>\r
+\r
+#include <sys/cdefs.h>\r
+\r
+//#include "namespace.h"\r
+//#include <libgen.h>\r
+#include <limits.h>\r
+#include <string.h>\r
+\r
+#ifdef __weak_alias\r
+__weak_alias(dirname,_dirname)\r
+#endif\r
+\r
+#if !HAVE_DIRNAME\r
+char *\r
+dirname(char *path)\r
+{\r
+  static char singledot[] = ".";\r
+  static char result[PATH_MAX];\r
+  const char *lastp;\r
+  size_t len;\r
+\r
+  /*\r
+   * If `path' is a null pointer or points to an empty string,\r
+   * return a pointer to the string ".".\r
+   */\r
+  if ((path == NULL) || (*path == '\0'))\r
+    return (singledot);\r
+\r
+  /* Strip trailing slashes, if any. */\r
+  lastp = path + strlen(path) - 1;\r
+  while (lastp != path && *lastp == '/')\r
+    lastp--;\r
+\r
+  /* Terminate path at the last occurence of '/'. */\r
+  do {\r
+    if (*lastp == '/') {\r
+      /* Strip trailing slashes, if any. */\r
+      while (lastp != path && *lastp == '/')\r
+        lastp--;\r
+\r
+      /* ...and copy the result into the result buffer. */\r
+      len = (lastp - path) + 1 /* last char */;\r
+      if (len > (PATH_MAX - 1))\r
+        len = PATH_MAX - 1;\r
+\r
+      memcpy(result, path, len);\r
+      result[len] = '\0';\r
+\r
+      return (result);\r
+    }\r
+  } while (--lastp >= path);\r
+\r
+  /* No /'s found, return a pointer to the string ".". */\r
+  return (singledot);\r
+}\r
+#endif\r
diff --git a/StdLib/PosixLib/Glob/DirFunctions.c b/StdLib/PosixLib/Glob/DirFunctions.c
new file mode 100644 (file)
index 0000000..db495e3
--- /dev/null
@@ -0,0 +1,135 @@
+/** @file\r
+  Implement the opendir, closedir, and readdir functions.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "internal.h"\r
+#include <Library/ShellLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseLib.h>\r
+\r
+typedef struct {\r
+  UINT32            Signature;\r
+  SHELL_FILE_HANDLE DirHandle;\r
+  EFI_FILE_INFO     *FileInfo;\r
+  struct dirent     *DirentStructure;\r
+} DIR_STRUCTURE;\r
+  \r
+DIR *                  opendir(const char * AsciiFileName)\r
+{\r
+  EFI_STATUS        Status;\r
+  DIR_STRUCTURE     *DirStruct;\r
+  CHAR16            *FileName;\r
+\r
+  DirStruct = (DIR_STRUCTURE*)AllocateZeroPool(sizeof(DIR_STRUCTURE));\r
+  if (DirStruct == NULL) {\r
+    errno = ENOMEM;\r
+    return NULL;\r
+  }\r
+\r
+  FileName = (CHAR16*)AllocateZeroPool((1+AsciiStrLen(AsciiFileName))*sizeof(CHAR16));\r
+  if (FileName == NULL) {\r
+    FreePool(DirStruct);\r
+    errno = ENOMEM;\r
+    return NULL;\r
+  }\r
+  AsciiStrToUnicodeStr(AsciiFileName, FileName);\r
+\r
+  Status = ShellOpenFileByName(FileName, &DirStruct->DirHandle, EFI_FILE_MODE_READ, 0);\r
+  FreePool(FileName);\r
+  if (EFI_ERROR(Status)) {\r
+    errno = ENOENT;\r
+    FreePool(DirStruct);\r
+    return NULL;\r
+  }\r
+  DirStruct->Signature = 0x08675309;\r
+  return ((DIR*)DirStruct);\r
+}\r
+\r
+int                    closedir(DIR * DirPointer)\r
+{\r
+  DIR_STRUCTURE     *DirStruct;\r
+\r
+  if (DirPointer == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  DirStruct = (DIR_STRUCTURE*)DirPointer;\r
+  if (DirStruct->Signature != 0x08675309) {\r
+    return 0;\r
+  }\r
+\r
+  ShellCloseFile(DirStruct->DirHandle);\r
+  SHELL_FREE_NON_NULL(DirStruct->FileInfo);\r
+  SHELL_FREE_NON_NULL(DirStruct->DirentStructure);\r
+  SHELL_FREE_NON_NULL(DirStruct);\r
+  \r
+  return 0;\r
+}\r
+\r
+struct dirent *        readdir(DIR * DirPointer)\r
+{\r
+  DIR_STRUCTURE     *DirStruct;\r
+  EFI_STATUS        Status;\r
+  BOOLEAN           NoFile;\r
+\r
+  NoFile = FALSE;\r
+\r
+  if (DirPointer == NULL) {\r
+    errno = EBADF;\r
+    return NULL;\r
+  }\r
+\r
+  DirStruct = (DIR_STRUCTURE*)DirPointer;\r
+  if (DirStruct->Signature != 0x08675309) {\r
+    errno = EBADF;\r
+    return NULL;\r
+  }\r
+\r
+  if (DirStruct->FileInfo == NULL) {\r
+    Status = ShellFindFirstFile(DirStruct->DirHandle, &(DirStruct->FileInfo));\r
+  } else {\r
+    Status = ShellFindNextFile(DirStruct->DirHandle, DirStruct->FileInfo, &NoFile);\r
+  }\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    errno = ENOENT;\r
+    return NULL;\r
+  }\r
+\r
+  if (NoFile) {\r
+    return (NULL);\r
+  }\r
+\r
+  SHELL_FREE_NON_NULL(DirStruct->DirentStructure);\r
+\r
+  DirStruct->DirentStructure = AllocateZeroPool(sizeof(DIR_STRUCTURE)+(StrSize(DirStruct->FileInfo->FileName)));\r
+  if (DirStruct->DirentStructure == NULL) {\r
+    errno = ENOMEM;\r
+    return NULL;\r
+  }\r
+\r
+  StrCpy(DirStruct->FileInfo->FileName, DirStruct->DirentStructure->FileName);\r
+\r
+  DirStruct->DirentStructure->FileSize                 = DirStruct->FileInfo->FileSize;\r
+  DirStruct->DirentStructure->PhysicalSize             = DirStruct->FileInfo->PhysicalSize;\r
+  DirStruct->DirentStructure->Attribute                = DirStruct->FileInfo->Attribute;\r
+  DirStruct->DirentStructure->CreateTime.tv_sec        = Efi2Time(&DirStruct->FileInfo->CreateTime);\r
+  DirStruct->DirentStructure->CreateTime.tv_nsec       = DirStruct->FileInfo->CreateTime.Nanosecond;\r
+  DirStruct->DirentStructure->LastAccessTime.tv_nsec   = Efi2Time(&DirStruct->FileInfo->LastAccessTime);\r
+  DirStruct->DirentStructure->LastAccessTime.tv_sec    = DirStruct->FileInfo->LastAccessTime.Nanosecond;\r
+  DirStruct->DirentStructure->ModificationTime.tv_sec  = Efi2Time(&DirStruct->FileInfo->ModificationTime);\r
+  DirStruct->DirentStructure->ModificationTime.tv_nsec = DirStruct->FileInfo->ModificationTime.Nanosecond;\r
+  DirStruct->DirentStructure->Size                     = StrSize(DirStruct->DirentStructure->FileName) + sizeof(DIR_STRUCTURE);\r
+\r
+  return (DirStruct->DirentStructure);\r
+}\r
diff --git a/StdLib/PosixLib/Glob/LibGlob.inf b/StdLib/PosixLib/Glob/LibGlob.inf
new file mode 100644 (file)
index 0000000..fab4730
--- /dev/null
@@ -0,0 +1,47 @@
+##  @file\r
+#   Library used for supplying glob POSIX routines.\r
+#\r
+#  Copyright (c) 2011, Intel Corporation. All rights reserved. <BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = LibGlob\r
+  FILE_GUID                      = 1D57B5D5-BAB4-4d2b-B7EB-0EB41D7B189C\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = LibGlob|UEFI_APPLICATION UEFI_DRIVER\r
+\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  DirFunctions.c\r
+  glob.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+  StdLibPrivateInternalFiles/DoNotUse.dec\r
+\r
+[Libraries]\r
+  MemoryAllocationLib\r
+  ShellLib\r
+  BaseLib\r
+  LibStdio\r
+  LibStdLib\r
+  LibString\r
+\r
+[Pcd]\r
diff --git a/StdLib/PosixLib/Glob/glob.c b/StdLib/PosixLib/Glob/glob.c
new file mode 100644 (file)
index 0000000..dec78d8
--- /dev/null
@@ -0,0 +1,1033 @@
+/** @file\r
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.\r
+ *\r
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).\r
+ *\r
+ * Optional extra services, controlled by flags not defined by POSIX:\r
+ *\r
+ * GLOB_MAGCHAR:\r
+ *  Set in gl_flags if pattern contained a globbing character.\r
+ * GLOB_NOMAGIC:\r
+ *  Same as GLOB_NOCHECK, but it will only append pattern if it did\r
+ *  not contain any magic characters.  [Used in csh style globbing]\r
+ * GLOB_ALTDIRFUNC:\r
+ *  Use alternately specified directory access functions.\r
+ * GLOB_TILDE:\r
+ *  expand ~user/foo to the /home/dir/of/user/foo\r
+ * GLOB_BRACE:\r
+ *  expand {1,2}{a,b} to 1a 1b 2a 2b\r
+ * GLOB_PERIOD:\r
+ *  allow metacharacters to match leading dots in filenames.\r
+ * GLOB_NO_DOTDIRS:\r
+ *  . and .. are hidden from wildcards, even if GLOB_PERIOD is set.\r
+ * gl_matchc:\r
+ *  Number of matches in the current invocation of glob.\r
+ *\r
+ * Copyright (c) 1989, 1993\r
+ *  The Regents of the University of California.  All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to Berkeley by\r
+ * Guido van Rossum.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the University nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+\r
+    glob.c  8.3 (Berkeley) 10/13/93\r
+    NetBSD: glob.c,v 1.23.4.1 2010/07/19 18:14:08 riz Exp\r
+ */\r
+#pragma warning ( disable : 4244 )\r
+#pragma warning ( disable : 4018 )\r
+\r
+#include  <LibConfig.h>\r
+\r
+#include <sys/cdefs.h>\r
+\r
+#include <sys/param.h>\r
+#include <sys/stat.h>\r
+\r
+#include <assert.h>\r
+#include <ctype.h>\r
+#include <dirent.h>\r
+#include <errno.h>\r
+#include <glob.h>\r
+//#include <pwd.h>\r
+#include <stdio.h>\r
+#include <stddef.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <sys/fcntl.h>\r
+#include "internal.h"\r
+\r
+#ifdef HAVE_NBTOOL_CONFIG_H\r
+#define NO_GETPW_R\r
+#endif\r
+\r
+#define GLOB_LIMIT_MALLOC     65536\r
+#define GLOB_LIMIT_STAT         128\r
+#define GLOB_LIMIT_READDIR    16384\r
+\r
+#define GLOB_INDEX_MALLOC         0\r
+#define GLOB_INDEX_STAT           1\r
+#define GLOB_INDEX_READDIR        2\r
+\r
+/*\r
+ * XXX: For NetBSD 1.4.x compatibility. (kill me l8r)\r
+ */\r
+#ifndef _DIAGASSERT\r
+#define _DIAGASSERT(a)\r
+#endif\r
+\r
+#define DOLLAR        '$'\r
+#define DOT           '.'\r
+#define EOS           '\0'\r
+#define LBRACKET      '['\r
+#define NOT           '!'\r
+#define QUESTION      '?'\r
+#define QUOTE         '\\'\r
+#define RANGE         '-'\r
+#define RBRACKET      ']'\r
+#define SEP           '/'\r
+#define STAR          '*'\r
+#define TILDE         '~'\r
+#define UNDERSCORE    '_'\r
+#define LBRACE        '{'\r
+#define RBRACE        '}'\r
+#define SLASH         '/'\r
+#define COMMA         ','\r
+\r
+#ifndef USE_8BIT_CHARS\r
+\r
+#define M_QUOTE       0x8000\r
+#define M_PROTECT     0x4000\r
+#define M_MASK        0xffff\r
+#define M_ASCII       0x00ff\r
+\r
+typedef u_short Char;\r
+\r
+#else\r
+\r
+#define M_QUOTE       (Char)0x80\r
+#define M_PROTECT     (Char)0x40\r
+#define M_MASK        (Char)0xff\r
+#define M_ASCII       (Char)0x7f\r
+\r
+typedef char Char;\r
+\r
+#endif\r
+\r
+\r
+#define CHAR(c)       ((Char)((c)&M_ASCII))\r
+#define META(c)       ((Char)((c)|M_QUOTE))\r
+#define M_ALL         META('*')\r
+#define M_END         META(']')\r
+#define M_NOT         META('!')\r
+#define M_ONE         META('?')\r
+#define M_RNG         META('-')\r
+#define M_SET         META('[')\r
+#define ismeta(c)     (((c)&M_QUOTE) != 0)\r
+\r
+static int            compare(const void *, const void *);\r
+static int            g_Ctoc(const Char *, char *, size_t);\r
+static int            g_lstat(Char *, __gl_stat_t  *, glob_t *);\r
+static DIR           *g_opendir(Char *, glob_t *);\r
+static Char          *g_strchr(const Char *, int);\r
+static int            g_stat(Char *, __gl_stat_t *, glob_t *);\r
+static int            glob0(const Char *, glob_t *, size_t *);\r
+static int            glob1(Char *, glob_t *, size_t *);\r
+static int            glob2(Char *, Char *, Char *, Char *, glob_t *, size_t *);\r
+static int            glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *);\r
+static int            globextend(const Char *, glob_t *, size_t *);\r
+static const Char    *globtilde(const Char *, Char *, size_t, glob_t *);\r
+static int            globexp1(const Char *, glob_t *, size_t *);\r
+static int            globexp2(const Char *, const Char *, glob_t *, int *, size_t *);\r
+static int            match(Char *, Char *, Char *);\r
+#ifdef DEBUG\r
+static void           qprintf(const char *, Char *);\r
+#endif\r
+\r
+int\r
+glob(\r
+  const char *pattern,\r
+  int flags,\r
+  int (*errfunc)(const char *, int),\r
+  glob_t *pglob\r
+)\r
+{\r
+  const u_char *patnext;\r
+  int c;\r
+  Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];\r
+  /* 0 = malloc(), 1 = stat(), 2 = readdir() */\r
+  size_t limit[] = { 0, 0, 0 };\r
+\r
+  _DIAGASSERT(pattern != NULL);\r
+\r
+  patnext = (const u_char *) pattern;\r
+  if (!(flags & GLOB_APPEND)) {\r
+    pglob->gl_pathc = 0;\r
+    pglob->gl_pathv = NULL;\r
+    if (!(flags & GLOB_DOOFFS))\r
+      pglob->gl_offs = 0;\r
+  }\r
+  pglob->gl_flags = flags & ~GLOB_MAGCHAR;\r
+  pglob->gl_errfunc = errfunc;\r
+  pglob->gl_matchc = 0;\r
+\r
+  bufnext = patbuf;\r
+  bufend = bufnext + MAXPATHLEN;\r
+  if (flags & GLOB_NOESCAPE) {\r
+    while (bufnext < bufend && (c = *patnext++) != EOS)\r
+      *bufnext++ = c;\r
+  } else {\r
+    /* Protect the quoted characters. */\r
+    while (bufnext < bufend && (c = *patnext++) != EOS)\r
+      if (c == QUOTE) {\r
+        if ((c = *patnext++) == EOS) {\r
+          c = QUOTE;\r
+          --patnext;\r
+        }\r
+        *bufnext++ = c | M_PROTECT;\r
+      }\r
+      else\r
+        *bufnext++ = c;\r
+  }\r
+  *bufnext = EOS;\r
+\r
+  if (flags & GLOB_BRACE)\r
+      return globexp1(patbuf, pglob, limit);\r
+  else\r
+      return glob0(patbuf, pglob, limit);\r
+}\r
+\r
+/*\r
+ * Expand recursively a glob {} pattern. When there is no more expansion\r
+ * invoke the standard globbing routine to glob the rest of the magic\r
+ * characters\r
+ */\r
+static int\r
+globexp1(const Char *pattern, glob_t *pglob, size_t *limit)\r
+{\r
+  const Char* ptr = pattern;\r
+  int rv;\r
+\r
+  _DIAGASSERT(pattern != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  /* Protect a single {}, for find(1), like csh */\r
+  if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)\r
+    return glob0(pattern, pglob, limit);\r
+\r
+  while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)\r
+    if (!globexp2(ptr, pattern, pglob, &rv, limit))\r
+      return rv;\r
+\r
+  return glob0(pattern, pglob, limit);\r
+}\r
+\r
+\r
+/*\r
+ * Recursive brace globbing helper. Tries to expand a single brace.\r
+ * If it succeeds then it invokes globexp1 with the new pattern.\r
+ * If it fails then it tries to glob the rest of the pattern and returns.\r
+ */\r
+static int\r
+globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv,\r
+    size_t *limit)\r
+{\r
+  int     i;\r
+  Char   *lm, *ls;\r
+  const Char *pe, *pm, *pl;\r
+  Char    patbuf[MAXPATHLEN + 1];\r
+\r
+  _DIAGASSERT(ptr != NULL);\r
+  _DIAGASSERT(pattern != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+  _DIAGASSERT(rv != NULL);\r
+\r
+  /* copy part up to the brace */\r
+  for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)\r
+    continue;\r
+  ls = lm;\r
+\r
+  /* Find the balanced brace */\r
+  for (i = 0, pe = ++ptr; *pe; pe++)\r
+    if (*pe == LBRACKET) {\r
+      /* Ignore everything between [] */\r
+      for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)\r
+        continue;\r
+      if (*pe == EOS) {\r
+        /*\r
+         * We could not find a matching RBRACKET.\r
+         * Ignore and just look for RBRACE\r
+         */\r
+        pe = pm;\r
+      }\r
+    }\r
+    else if (*pe == LBRACE)\r
+      i++;\r
+    else if (*pe == RBRACE) {\r
+      if (i == 0)\r
+        break;\r
+      i--;\r
+    }\r
+\r
+  /* Non matching braces; just glob the pattern */\r
+  if (i != 0 || *pe == EOS) {\r
+    /*\r
+     * we use `pattern', not `patbuf' here so that that\r
+     * unbalanced braces are passed to the match\r
+     */\r
+    *rv = glob0(pattern, pglob, limit);\r
+    return 0;\r
+  }\r
+\r
+  for (i = 0, pl = pm = ptr; pm <= pe; pm++) {\r
+    switch (*pm) {\r
+    case LBRACKET:\r
+      /* Ignore everything between [] */\r
+      for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)\r
+        continue;\r
+      if (*pm == EOS) {\r
+        /*\r
+         * We could not find a matching RBRACKET.\r
+         * Ignore and just look for RBRACE\r
+         */\r
+        pm = pl;\r
+      }\r
+      break;\r
+\r
+    case LBRACE:\r
+      i++;\r
+      break;\r
+\r
+    case RBRACE:\r
+      if (i) {\r
+        i--;\r
+        break;\r
+      }\r
+      /* FALLTHROUGH */\r
+    case COMMA:\r
+      if (i && *pm == COMMA)\r
+        break;\r
+      else {\r
+        /* Append the current string */\r
+        for (lm = ls; (pl < pm); *lm++ = *pl++)\r
+          continue;\r
+        /*\r
+         * Append the rest of the pattern after the\r
+         * closing brace\r
+         */\r
+        for (pl = pe + 1; (*lm++ = *pl++) != EOS;)\r
+          continue;\r
+\r
+        /* Expand the current pattern */\r
+#ifdef DEBUG\r
+        qprintf("globexp2:", patbuf);\r
+#endif\r
+        *rv = globexp1(patbuf, pglob, limit);\r
+\r
+        /* move after the comma, to the next string */\r
+        pl = pm + 1;\r
+      }\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+  *rv = 0;\r
+  return 0;\r
+}\r
+\r
+\r
+\r
+/*\r
+ * expand tilde from the passwd file.\r
+ */\r
+static const Char *\r
+globtilde(const Char *pattern, Char *patbuf, size_t patsize, glob_t *pglob)\r
+{\r
+  const char *h;\r
+  const Char *p;\r
+  Char *b;\r
+  char *d;\r
+  Char *pend = &patbuf[patsize / sizeof(Char)];\r
+\r
+  pend--;\r
+\r
+  _DIAGASSERT(pattern != NULL);\r
+  _DIAGASSERT(patbuf != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))\r
+    return pattern;\r
+\r
+  /* Copy up to the end of the string or / */\r
+  for (p = pattern + 1, d = (char *)(void *)patbuf;\r
+       d < (char *)(void *)pend && *p && *p != SLASH;\r
+       *d++ = *p++)\r
+    continue;\r
+\r
+  if (d == (char *)(void *)pend)\r
+    return NULL;\r
+\r
+  *d = EOS;\r
+  d = (char *)(void *)patbuf;\r
+\r
+  if (*d == EOS) {\r
+    /*\r
+     * handle a plain ~ or ~/ by expanding $HOME\r
+     * first and then trying the password file\r
+     */\r
+    if ((h = getenv("HOME")) == NULL) {\r
+      return pattern;\r
+    }\r
+  }\r
+  else {\r
+    /*\r
+     * Expand a ~user\r
+     */\r
+    return pattern;\r
+  }\r
+\r
+  /* Copy the home directory */\r
+  for (b = patbuf; b < pend && *h; *b++ = *h++)\r
+    continue;\r
+\r
+  if (b == pend)\r
+    return NULL;\r
+\r
+  /* Append the rest of the pattern */\r
+  while (b < pend && (*b++ = *p++) != EOS)\r
+    continue;\r
+\r
+  if (b == pend)\r
+    return NULL;\r
+\r
+  return patbuf;\r
+}\r
+\r
+\r
+/*\r
+ * The main glob() routine: compiles the pattern (optionally processing\r
+ * quotes), calls glob1() to do the real pattern matching, and finally\r
+ * sorts the list (unless unsorted operation is requested).  Returns 0\r
+ * if things went well, nonzero if errors occurred.  It is not an error\r
+ * to find no matches.\r
+ */\r
+static int\r
+glob0(const Char *pattern, glob_t *pglob, size_t *limit)\r
+{\r
+  const Char *qpatnext;\r
+  int c, error;\r
+  __gl_size_t oldpathc;\r
+  Char *bufnext, patbuf[MAXPATHLEN+1];\r
+\r
+  _DIAGASSERT(pattern != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  if ((qpatnext = globtilde(pattern, patbuf, sizeof(patbuf),\r
+      pglob)) == NULL)\r
+    return GLOB_ABEND;\r
+  oldpathc = pglob->gl_pathc;\r
+  bufnext = patbuf;\r
+\r
+  /* We don't need to check for buffer overflow any more. */\r
+  while ((c = *qpatnext++) != EOS) {\r
+    switch (c) {\r
+    case LBRACKET:\r
+      c = *qpatnext;\r
+      if (c == NOT)\r
+        ++qpatnext;\r
+      if (*qpatnext == EOS ||\r
+          g_strchr(qpatnext+1, RBRACKET) == NULL) {\r
+        *bufnext++ = LBRACKET;\r
+        if (c == NOT)\r
+          --qpatnext;\r
+        break;\r
+      }\r
+      *bufnext++ = M_SET;\r
+      if (c == NOT)\r
+        *bufnext++ = M_NOT;\r
+      c = *qpatnext++;\r
+      do {\r
+        *bufnext++ = CHAR(c);\r
+        if (*qpatnext == RANGE &&\r
+            (c = qpatnext[1]) != RBRACKET) {\r
+          *bufnext++ = M_RNG;\r
+          *bufnext++ = CHAR(c);\r
+          qpatnext += 2;\r
+        }\r
+      } while ((c = *qpatnext++) != RBRACKET);\r
+      pglob->gl_flags |= GLOB_MAGCHAR;\r
+      *bufnext++ = M_END;\r
+      break;\r
+    case QUESTION:\r
+      pglob->gl_flags |= GLOB_MAGCHAR;\r
+      *bufnext++ = M_ONE;\r
+      break;\r
+    case STAR:\r
+      pglob->gl_flags |= GLOB_MAGCHAR;\r
+      /* collapse adjacent stars to one,\r
+       * to avoid exponential behavior\r
+       */\r
+      if (bufnext == patbuf || bufnext[-1] != M_ALL)\r
+        *bufnext++ = M_ALL;\r
+      break;\r
+    default:\r
+      *bufnext++ = CHAR(c);\r
+      break;\r
+    }\r
+  }\r
+  *bufnext = EOS;\r
+#ifdef DEBUG\r
+  qprintf("glob0:", patbuf);\r
+#endif\r
+\r
+  if ((error = glob1(patbuf, pglob, limit)) != 0)\r
+    return error;\r
+\r
+  if (pglob->gl_pathc == oldpathc) {\r
+    /*\r
+     * If there was no match we are going to append the pattern\r
+     * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was\r
+     * specified and the pattern did not contain any magic\r
+     * characters GLOB_NOMAGIC is there just for compatibility\r
+     * with csh.\r
+     */\r
+    if ((pglob->gl_flags & GLOB_NOCHECK) ||\r
+        ((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR))\r
+         == GLOB_NOMAGIC)) {\r
+      return globextend(pattern, pglob, limit);\r
+    } else {\r
+      return GLOB_NOMATCH;\r
+    }\r
+  } else if (!(pglob->gl_flags & GLOB_NOSORT)) {\r
+    qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,\r
+        (size_t)pglob->gl_pathc - oldpathc, sizeof(char *),\r
+        compare);\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+static int\r
+compare(const void *p, const void *q)\r
+{\r
+\r
+  _DIAGASSERT(p != NULL);\r
+  _DIAGASSERT(q != NULL);\r
+\r
+  return strcoll(*(const char * const *)p, *(const char * const *)q);\r
+}\r
+\r
+static int\r
+glob1(Char *pattern, glob_t *pglob, size_t *limit)\r
+{\r
+  Char pathbuf[MAXPATHLEN+1];\r
+\r
+  _DIAGASSERT(pattern != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */\r
+  if (*pattern == EOS)\r
+    return 0;\r
+  /*\r
+   * we save one character so that we can use ptr >= limit,\r
+   * in the general case when we are appending non nul chars only.\r
+   */\r
+  return glob2(pathbuf, pathbuf,\r
+      pathbuf + (sizeof(pathbuf) / sizeof(*pathbuf)) - 1, pattern,\r
+      pglob, limit);\r
+}\r
+\r
+/*\r
+ * The functions glob2 and glob3 are mutually recursive; there is one level\r
+ * of recursion for each segment in the pattern that contains one or more\r
+ * meta characters.\r
+ */\r
+static int\r
+glob2(Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern, glob_t *pglob,\r
+    size_t *limit)\r
+{\r
+  __gl_stat_t sb;\r
+  Char *p, *q;\r
+  int anymeta;\r
+  Char *pend;\r
+  ptrdiff_t diff;\r
+\r
+  _DIAGASSERT(pathbuf != NULL);\r
+  _DIAGASSERT(pathend != NULL);\r
+  _DIAGASSERT(pattern != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  /*\r
+   * Loop over pattern segments until end of pattern or until\r
+   * segment with meta character found.\r
+   */\r
+  for (anymeta = 0;;) {\r
+    if (*pattern == EOS) {    /* End of pattern? */\r
+      *pathend = EOS;\r
+      if (g_lstat(pathbuf, &sb, pglob))\r
+        return 0;\r
+\r
+      if ((pglob->gl_flags & GLOB_LIMIT) &&\r
+          limit[GLOB_INDEX_STAT]++ >= GLOB_LIMIT_STAT) {\r
+        errno = 0;\r
+        *pathend++ = SEP;\r
+        *pathend = EOS;\r
+        return GLOB_NOSPACE;\r
+      }\r
+      if (((pglob->gl_flags & GLOB_MARK) &&\r
+          pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||\r
+//          (S_ISLNK(sb.st_mode) &&\r
+          (0 &&\r
+          (g_stat(pathbuf, &sb, pglob) == 0) &&\r
+          S_ISDIR(sb.st_mode)))) {\r
+        if (pathend >= pathlim)\r
+          return GLOB_ABORTED;\r
+        *pathend++ = SEP;\r
+        *pathend = EOS;\r
+      }\r
+      ++pglob->gl_matchc;\r
+      return globextend(pathbuf, pglob, limit);\r
+    }\r
+\r
+    /* Find end of next segment, copy tentatively to pathend. */\r
+    q = pathend;\r
+    p = pattern;\r
+    while (*p != EOS && *p != SEP) {\r
+      if (ismeta(*p))\r
+        anymeta = 1;\r
+      if (q >= pathlim)\r
+        return GLOB_ABORTED;\r
+      *q++ = *p++;\r
+    }\r
+\r
+                /*\r
+     * No expansion, or path ends in slash-dot shash-dot-dot,\r
+     * do next segment.\r
+     */\r
+    if (pglob->gl_flags & GLOB_PERIOD) {\r
+      for (pend = pathend; pend > pathbuf && pend[-1] == '/';\r
+          pend--)\r
+        continue;\r
+      diff = pend - pathbuf;\r
+    } else {\r
+      /* XXX: GCC */\r
+      diff = 0;\r
+      pend = pathend;\r
+    }\r
+\r
+                if ((!anymeta) ||\r
+        ((pglob->gl_flags & GLOB_PERIOD) &&\r
+         (diff >= 1 && pend[-1] == DOT) &&\r
+         (diff >= 2 && (pend[-2] == SLASH || pend[-2] == DOT)) &&\r
+         (diff < 3 || pend[-3] == SLASH))) {\r
+      pathend = q;\r
+      pattern = p;\r
+      while (*pattern == SEP) {\r
+        if (pathend >= pathlim)\r
+          return GLOB_ABORTED;\r
+        *pathend++ = *pattern++;\r
+      }\r
+    } else      /* Need expansion, recurse. */\r
+      return glob3(pathbuf, pathend, pathlim, pattern, p,\r
+          pglob, limit);\r
+  }\r
+  /* NOTREACHED */\r
+}\r
+\r
+static int\r
+glob3(Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern,\r
+    Char *restpattern, glob_t *pglob, size_t *limit)\r
+{\r
+  struct dirent *dp;\r
+  DIR *dirp;\r
+  int error;\r
+  char buf[MAXPATHLEN];\r
+\r
+  /*\r
+   * The readdirfunc declaration can't be prototyped, because it is\r
+   * assigned, below, to two functions which are prototyped in glob.h\r
+   * and dirent.h as taking pointers to differently typed opaque\r
+   * structures.\r
+   */\r
+  struct dirent *(*readdirfunc)(void *);\r
+\r
+  _DIAGASSERT(pathbuf != NULL);\r
+  _DIAGASSERT(pathend != NULL);\r
+  _DIAGASSERT(pattern != NULL);\r
+  _DIAGASSERT(restpattern != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  *pathend = EOS;\r
+  errno = 0;\r
+\r
+  if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {\r
+    if (pglob->gl_errfunc) {\r
+      if (g_Ctoc(pathbuf, buf, sizeof(buf)))\r
+        return GLOB_ABORTED;\r
+      if (pglob->gl_errfunc(buf, errno) ||\r
+          pglob->gl_flags & GLOB_ERR)\r
+        return GLOB_ABORTED;\r
+    }\r
+    /*\r
+     * Posix/XOpen: glob should return when it encounters a\r
+     * directory that it cannot open or read\r
+     * XXX: Should we ignore ENOTDIR and ENOENT though?\r
+     * I think that Posix had in mind EPERM...\r
+     */\r
+    if (pglob->gl_flags & GLOB_ERR)\r
+      return GLOB_ABORTED;\r
+\r
+    return 0;\r
+  }\r
+\r
+  error = 0;\r
+\r
+  /* Search directory for matching names. */\r
+  if (pglob->gl_flags & GLOB_ALTDIRFUNC)\r
+    readdirfunc = pglob->gl_readdir;\r
+  else\r
+    readdirfunc = (struct dirent *(*)(void *)) readdir;\r
+  while ((dp = (*readdirfunc)(dirp)) != NULL) {\r
+    u_char *sc;\r
+    Char *dc;\r
+\r
+    if ((pglob->gl_flags & GLOB_LIMIT) &&\r
+        limit[GLOB_INDEX_READDIR]++ >= GLOB_LIMIT_READDIR) {\r
+      errno = 0;\r
+      *pathend++ = SEP;\r
+      *pathend = EOS;\r
+      return GLOB_NOSPACE;\r
+    }\r
+\r
+    /*\r
+     * Initial DOT must be matched literally, unless we have\r
+     * GLOB_PERIOD set.\r
+     */\r
+    if ((pglob->gl_flags & GLOB_PERIOD) == 0)\r
+      if (dp->FileName[0] == DOT && *pattern != DOT)\r
+        continue;\r
+    /*\r
+     * If GLOB_NO_DOTDIRS is set, . and .. vanish.\r
+     */\r
+    if ((pglob->gl_flags & GLOB_NO_DOTDIRS) &&\r
+        (dp->FileName[0] == DOT) &&\r
+        ((dp->FileName[1] == EOS) ||\r
+         ((dp->FileName[1] == DOT) && (dp->FileName[2] == EOS))))\r
+      continue;\r
+    /*\r
+     * The resulting string contains EOS, so we can\r
+     * use the pathlim character, if it is the nul\r
+     */\r
+    for (sc = (u_char *) dp->FileName, dc = pathend;\r
+         dc <= pathlim && (*dc++ = *sc++) != EOS;)\r
+      continue;\r
+\r
+    /*\r
+     * Have we filled the buffer without seeing EOS?\r
+     */\r
+    if (dc > pathlim && *pathlim != EOS) {\r
+      /*\r
+       * Abort when requested by caller, otherwise\r
+       * reset pathend back to last SEP and continue\r
+       * with next dir entry.\r
+       */\r
+      if (pglob->gl_flags & GLOB_ERR) {\r
+        error = GLOB_ABORTED;\r
+        break;\r
+      }\r
+      else {\r
+        *pathend = EOS;\r
+        continue;\r
+      }\r
+    }\r
+\r
+    if (!match(pathend, pattern, restpattern)) {\r
+      *pathend = EOS;\r
+      continue;\r
+    }\r
+    error = glob2(pathbuf, --dc, pathlim, restpattern, pglob,\r
+        limit);\r
+    if (error)\r
+      break;\r
+  }\r
+\r
+  if (pglob->gl_flags & GLOB_ALTDIRFUNC)\r
+    (*pglob->gl_closedir)(dirp);\r
+  else\r
+    closedir(dirp);\r
+\r
+  /*\r
+   * Again Posix X/Open issue with regards to error handling.\r
+   */\r
+  if ((error || errno) && (pglob->gl_flags & GLOB_ERR))\r
+    return GLOB_ABORTED;\r
+\r
+  return error;\r
+}\r
+\r
+\r
+/*\r
+ * Extend the gl_pathv member of a glob_t structure to accommodate a new item,\r
+ * add the new item, and update gl_pathc.\r
+ *\r
+ * This assumes the BSD realloc, which only copies the block when its size\r
+ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic\r
+ * behavior.\r
+ *\r
+ * Return 0 if new item added, error code if memory couldn't be allocated.\r
+ *\r
+ * Invariant of the glob_t structure:\r
+ *  Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and\r
+ *  gl_pathv points to (gl_offs + gl_pathc + 1) items.\r
+ */\r
+static int\r
+globextend(const Char *path, glob_t *pglob, size_t *limit)\r
+{\r
+  char **pathv;\r
+  size_t i, newsize, len;\r
+  char *copy;\r
+  const Char *p;\r
+\r
+  _DIAGASSERT(path != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);\r
+  pathv = pglob->gl_pathv ? realloc(pglob->gl_pathv, newsize) :\r
+      malloc(newsize);\r
+  if (pathv == NULL)\r
+    return GLOB_NOSPACE;\r
+\r
+  if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {\r
+    /* first time around -- clear initial gl_offs items */\r
+    pathv += pglob->gl_offs;\r
+    for (i = pglob->gl_offs + 1; --i > 0; )\r
+      *--pathv = NULL;\r
+  }\r
+  pglob->gl_pathv = pathv;\r
+\r
+  for (p = path; *p++;)\r
+    continue;\r
+  len = (size_t)(p - path);\r
+  limit[GLOB_INDEX_MALLOC] += len;\r
+  if ((copy = malloc(len)) != NULL) {\r
+    if (g_Ctoc(path, copy, len)) {\r
+      free(copy);\r
+      return GLOB_ABORTED;\r
+    }\r
+    pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;\r
+  }\r
+  pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;\r
+\r
+  if ((pglob->gl_flags & GLOB_LIMIT) &&\r
+      (newsize + limit[GLOB_INDEX_MALLOC]) >= GLOB_LIMIT_MALLOC) {\r
+    errno = 0;\r
+    return GLOB_NOSPACE;\r
+  }\r
+\r
+  return copy == NULL ? GLOB_NOSPACE : 0;\r
+}\r
+\r
+\r
+/*\r
+ * pattern matching function for filenames.  Each occurrence of the *\r
+ * pattern causes a recursion level.\r
+ */\r
+static int\r
+match(Char *name, Char *pat, Char *patend)\r
+{\r
+  int ok, negate_range;\r
+  Char c, k;\r
+\r
+  _DIAGASSERT(name != NULL);\r
+  _DIAGASSERT(pat != NULL);\r
+  _DIAGASSERT(patend != NULL);\r
+\r
+  while (pat < patend) {\r
+    c = *pat++;\r
+    switch (c & M_MASK) {\r
+    case M_ALL:\r
+      if (pat == patend)\r
+        return 1;\r
+      do\r
+          if (match(name, pat, patend))\r
+            return 1;\r
+      while (*name++ != EOS);\r
+      return 0;\r
+    case M_ONE:\r
+      if (*name++ == EOS)\r
+        return 0;\r
+      break;\r
+    case M_SET:\r
+      ok = 0;\r
+      if ((k = *name++) == EOS)\r
+        return 0;\r
+      if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)\r
+        ++pat;\r
+      while (((c = *pat++) & M_MASK) != M_END)\r
+        if ((*pat & M_MASK) == M_RNG) {\r
+          if (c <= k && k <= pat[1])\r
+            ok = 1;\r
+          pat += 2;\r
+        } else if (c == k)\r
+          ok = 1;\r
+      if (ok == negate_range)\r
+        return 0;\r
+      break;\r
+    default:\r
+      if (*name++ != c)\r
+        return 0;\r
+      break;\r
+    }\r
+  }\r
+  return *name == EOS;\r
+}\r
+\r
+/* Free allocated data belonging to a glob_t structure. */\r
+void\r
+globfree(glob_t *pglob)\r
+{\r
+  size_t i;\r
+  char **pp;\r
+\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  if (pglob->gl_pathv != NULL) {\r
+    pp = pglob->gl_pathv + pglob->gl_offs;\r
+    for (i = pglob->gl_pathc; i--; ++pp)\r
+      if (*pp)\r
+        free(*pp);\r
+    free(pglob->gl_pathv);\r
+    pglob->gl_pathv = NULL;\r
+    pglob->gl_pathc = 0;\r
+  }\r
+}\r
+\r
+static DIR *\r
+g_opendir(Char *str, glob_t *pglob)\r
+{\r
+  char buf[MAXPATHLEN];\r
+\r
+  _DIAGASSERT(str != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  if (!*str)\r
+    (void)strlcpy(buf, ".", sizeof(buf));\r
+  else {\r
+    if (g_Ctoc(str, buf, sizeof(buf)))\r
+      return NULL;\r
+  }\r
+\r
+  if (pglob->gl_flags & GLOB_ALTDIRFUNC)\r
+    return (*pglob->gl_opendir)(buf);\r
+\r
+  return opendir(buf);\r
+}\r
+\r
+static int\r
+g_lstat(Char *fn, __gl_stat_t *sb, glob_t *pglob)\r
+{\r
+  char buf[MAXPATHLEN];\r
+\r
+  _DIAGASSERT(fn != NULL);\r
+  _DIAGASSERT(sb != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  if (g_Ctoc(fn, buf, sizeof(buf)))\r
+    return -1;\r
+  if (pglob->gl_flags & GLOB_ALTDIRFUNC)\r
+    return (*pglob->gl_lstat)(buf, sb);\r
+  return lstat(buf, sb);\r
+}\r
+\r
+static int\r
+g_stat(Char *fn, __gl_stat_t *sb, glob_t *pglob)\r
+{\r
+  char buf[MAXPATHLEN];\r
+\r
+  _DIAGASSERT(fn != NULL);\r
+  _DIAGASSERT(sb != NULL);\r
+  _DIAGASSERT(pglob != NULL);\r
+\r
+  if (g_Ctoc(fn, buf, sizeof(buf)))\r
+    return -1;\r
+  if (pglob->gl_flags & GLOB_ALTDIRFUNC)\r
+    return (*pglob->gl_stat)(buf, sb);\r
+  return stat(buf, sb);\r
+}\r
+\r
+static Char *\r
+g_strchr(const Char *str, int ch)\r
+{\r
+\r
+  _DIAGASSERT(str != NULL);\r
+\r
+  do {\r
+    if (*str == ch)\r
+      return __UNCONST(str);\r
+  } while (*str++);\r
+  return NULL;\r
+}\r
+\r
+static int\r
+g_Ctoc(const Char *str, char *buf, size_t len)\r
+{\r
+  char *dc;\r
+\r
+  _DIAGASSERT(str != NULL);\r
+  _DIAGASSERT(buf != NULL);\r
+\r
+  if (len == 0)\r
+    return 1;\r
+\r
+  for (dc = buf; len && (*dc++ = *str++) != EOS; len--)\r
+    continue;\r
+\r
+  return len == 0;\r
+}\r
+\r
+#ifdef DEBUG\r
+static void\r
+qprintf(const char *str, Char *s)\r
+{\r
+  Char *p;\r
+\r
+  _DIAGASSERT(str != NULL);\r
+  _DIAGASSERT(s != NULL);\r
+\r
+  (void)printf("%s:\n", str);\r
+  for (p = s; *p; p++)\r
+    (void)printf("%c", CHAR(*p));\r
+  (void)printf("\n");\r
+  for (p = s; *p; p++)\r
+    (void)printf("%c", *p & M_PROTECT ? '"' : ' ');\r
+  (void)printf("\n");\r
+  for (p = s; *p; p++)\r
+    (void)printf("%c", ismeta(*p) ? '_' : ' ');\r
+  (void)printf("\n");\r
+}\r
+#endif\r
diff --git a/StdLib/PosixLib/Glob/internal.h b/StdLib/PosixLib/Glob/internal.h
new file mode 100644 (file)
index 0000000..c65a7ca
--- /dev/null
@@ -0,0 +1,23 @@
+/** @file\r
+  Implement the invalid functions to return failures.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <dirent.h>\r
+#include <sysexits.h>\r
+\r
+typedef VOID* DIR;\r
+\r
+struct dirent *        readdir(DIR *);\r
+int                    closedir(DIR *);\r
+DIR *                  opendir(const char *);\r
diff --git a/StdLib/PosixLib/Stringlist/LibStringlist.inf b/StdLib/PosixLib/Stringlist/LibStringlist.inf
new file mode 100644 (file)
index 0000000..c441765
--- /dev/null
@@ -0,0 +1,41 @@
+##  @file\r
+#   Library used for supplying glob POSIX routines.\r
+#\r
+#  Copyright (c) 2011, Intel Corporation. All rights reserved. <BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = LibStringlist\r
+  FILE_GUID                      = 19D17940-BA8D-4fa7-A704-F33D9FAFAB9D\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = LibStringlist|UEFI_APPLICATION UEFI_DRIVER\r
+\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  stringlist.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  StdLib/StdLib.dec\r
+  StdLibPrivateInternalFiles/DoNotUse.dec\r
+\r
+[Libraries]\r
+  LibC\r
+  LibStdio\r
+  LibStdLib\r
+  LibString\r
diff --git a/StdLib/PosixLib/Stringlist/stringlist.c b/StdLib/PosixLib/Stringlist/stringlist.c
new file mode 100644 (file)
index 0000000..47e3bee
--- /dev/null
@@ -0,0 +1,154 @@
+/*     $NetBSD: stringlist.c,v 1.13 2008/04/28 20:22:59 martin Exp $\r
+\r
+ * Copyright (c) 1994, 1999 The NetBSD Foundation, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to The NetBSD Foundation\r
+ * by Christos Zoulas.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\r
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+#pragma warning ( disable : 4018 )\r
+\r
+#include <sys/cdefs.h>\r
+#if defined(LIBC_SCCS) && !defined(lint)\r
+__RCSID("$NetBSD: stringlist.c,v 1.13 2008/04/28 20:22:59 martin Exp $");\r
+#endif /* LIBC_SCCS and not lint */\r
+\r
+#include <assert.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stringlist.h>\r
+\r
+#ifdef __weak_alias\r
+__weak_alias(sl_add,_sl_add)\r
+__weak_alias(sl_find,_sl_find)\r
+__weak_alias(sl_free,_sl_free)\r
+__weak_alias(sl_init,_sl_init)\r
+__weak_alias(sl_delete,_sl_delete)\r
+#endif\r
+\r
+#define _SL_CHUNKSIZE  20\r
+\r
+/*\r
+ * sl_init(): Initialize a string list\r
+ */\r
+StringList *\r
+sl_init(void)\r
+{\r
+       StringList *sl;\r
+\r
+       sl = malloc(sizeof(StringList));\r
+       if (sl == NULL)\r
+               return NULL;\r
+\r
+       sl->sl_cur = 0;\r
+       sl->sl_max = _SL_CHUNKSIZE;\r
+       sl->sl_str = malloc(sl->sl_max * sizeof(char *));\r
+       if (sl->sl_str == NULL) {\r
+               free(sl);\r
+               sl = NULL;\r
+       }\r
+       return sl;\r
+}\r
+\r
+\r
+/*\r
+ * sl_add(): Add an item to the string list\r
+ */\r
+int\r
+sl_add(StringList *sl, char *name)\r
+{\r
+\r
+       _DIAGASSERT(sl != NULL);\r
+\r
+       if (sl->sl_cur == sl->sl_max - 1) {\r
+               char    **new;\r
+\r
+               new = realloc(sl->sl_str,\r
+                   (sl->sl_max + _SL_CHUNKSIZE) * sizeof(char *));\r
+               if (new == NULL)\r
+                       return -1;\r
+               sl->sl_max += _SL_CHUNKSIZE;\r
+               sl->sl_str = new;\r
+       }\r
+       sl->sl_str[sl->sl_cur++] = name;\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+ * sl_free(): Free a stringlist\r
+ */\r
+void\r
+sl_free(StringList *sl, int all)\r
+{\r
+       size_t i;\r
+\r
+       if (sl == NULL)\r
+               return;\r
+       if (sl->sl_str) {\r
+               if (all)\r
+                       for (i = 0; i < sl->sl_cur; i++)\r
+                               free(sl->sl_str[i]);\r
+               free(sl->sl_str);\r
+       }\r
+       free(sl);\r
+}\r
+\r
+\r
+/*\r
+ * sl_find(): Find a name in the string list\r
+ */\r
+char *\r
+sl_find(StringList *sl, const char *name)\r
+{\r
+       size_t i;\r
+\r
+       _DIAGASSERT(sl != NULL);\r
+\r
+       for (i = 0; i < sl->sl_cur; i++)\r
+               if (strcmp(sl->sl_str[i], name) == 0)\r
+                       return sl->sl_str[i];\r
+\r
+       return NULL;\r
+}\r
+\r
+int\r
+sl_delete(StringList *sl, const char *name, int all)\r
+{\r
+       size_t i, j;\r
+\r
+       for (i = 0; i < sl->sl_cur; i++)\r
+               if (strcmp(sl->sl_str[i], name) == 0) {\r
+                       if (all)\r
+                               free(sl->sl_str[i]);\r
+                       for (j = i + 1; j < sl->sl_cur; j++)\r
+                               sl->sl_str[j - 1] = sl->sl_str[j];\r
+                       sl->sl_str[--sl->sl_cur] = NULL;\r
+                       return 0;\r
+               }\r
+       return -1;\r
+}\r
+\r
diff --git a/StdLib/SocketDxe/ComponentName.c b/StdLib/SocketDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..7fe9c71
--- /dev/null
@@ -0,0 +1,182 @@
+/** @file\r
+  UEFI Component Name(2) protocol implementation.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Socket.h"\r
+\r
+/**\r
+  EFI Component Name Protocol declaration\r
+**/\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {\r
+  GetDriverName,\r
+  GetControllerName,\r
+  "eng"\r
+};\r
+\r
+/**\r
+  EFI Component Name 2 Protocol declaration\r
+**/\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {\r
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,\r
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,\r
+  "en"\r
+};\r
+\r
+\r
+/**\r
+  Driver name table declaration\r
+**/\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE\r
+mDriverNameTable[] = {\r
+  {"eng;en", L"Socket Layer Driver"},\r
+  {NULL,  NULL}\r
+};\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 3066 or ISO 639-2 language code format.\r
+  @param [out] ppDriverName     A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,\r
+  IN  CHAR8 * pLanguage,\r
+  OUT CHAR16 ** ppDriverName\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  Status = LookupUnicodeString2 (\r
+             pLanguage,\r
+             pThis->SupportedLanguages,\r
+             mDriverNameTable,\r
+             ppDriverName,\r
+             (BOOLEAN)(pThis == &gComponentName)\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+  @param [in] ControllerHandle  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+  @param [in] ChildHandle       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 3066 or ISO 639-2 language code format.\r
+  @param [out] ppControllerName A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,\r
+  IN  EFI_HANDLE ControllerHandle,\r
+  IN OPTIONAL EFI_HANDLE ChildHandle,\r
+  IN  CHAR8 * pLanguage,\r
+  OUT CHAR16 ** ppControllerName\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  // Set the controller name\r
+  //\r
+  *ppControllerName = L"Socket Layer";\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  // Return the operation status\r
+  //\r
+  DBG_EXIT_HEX ( Status );\r
+  return Status;\r
+}\r
diff --git a/StdLib/SocketDxe/DriverBinding.c b/StdLib/SocketDxe/DriverBinding.c
new file mode 100644 (file)
index 0000000..7de7f62
--- /dev/null
@@ -0,0 +1,198 @@
+/** @file\r
+  Implement the driver binding protocol for the socket layer.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Socket.h"\r
+\r
+/**\r
+  Verify the controller type\r
+\r
+  Determine if any of the network service binding protocols exist on\r
+  the controller handle.  If so, verify that these protocols are not\r
+  already in use.  Call ::DriverStart for any network service binding\r
+  protocol that is not in use.\r
+\r
+  @param [in] pThis                Protocol instance pointer.\r
+  @param [in] Controller           Handle of device to test.\r
+  @param [in] pRemainingDevicePath Not used.\r
+\r
+  @retval EFI_SUCCESS          This driver supports this device.\r
+  @retval other                This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,\r
+  IN EFI_HANDLE Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath\r
+  )\r
+{\r
+  CONST DT_SOCKET_BINDING * pEnd;\r
+  VOID * pInterface;\r
+  CONST DT_SOCKET_BINDING * pSocketBinding;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume the list is empty\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+\r
+  //\r
+  //  Walk the list of network connection points\r
+  //\r
+  pSocketBinding = &cEslSocketBinding[0];\r
+  pEnd = &pSocketBinding[ cEslSocketBindingEntries ];\r
+  while ( pEnd > pSocketBinding ) {\r
+    //\r
+    //  Determine if the controller supports the network protocol\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    pSocketBinding->pNetworkBinding,\r
+                    &pInterface,\r
+                    pThis->DriverBindingHandle,\r
+                    Controller,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Determine if the driver is already connected\r
+      //\r
+      Status = gBS->OpenProtocol (\r
+                      Controller,\r
+                      (EFI_GUID *)pSocketBinding->pTagGuid,\r
+                      &pInterface,\r
+                      pThis->DriverBindingHandle,\r
+                      Controller,\r
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                      );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        Status = EFI_ALREADY_STARTED;\r
+      }\r
+      else {\r
+        if ( EFI_UNSUPPORTED == Status ) {\r
+          //\r
+          //  Connect the driver since the tag is not present\r
+          //\r
+          Status = EFI_SUCCESS;\r
+        }\r
+      }\r
+    }\r
+\r
+    //\r
+    //  Set the next network protocol\r
+    //\r
+    pSocketBinding += 1;\r
+  }\r
+\r
+  //\r
+  //  Return the device supported status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Connect to the network service bindings\r
+\r
+  Walk the network service protocols on the controller handle and\r
+  locate any that are not in use.  Create service structures to\r
+  manage the service binding for the socket driver.\r
+\r
+  @param [in] pThis                Protocol instance pointer.\r
+  @param [in] Controller           Handle of device to work with.\r
+  @param [in] pRemainingDevicePath Not used, always produce all possible children.\r
+\r
+  @retval EFI_SUCCESS          This driver is added to Controller.\r
+  @retval other                This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,\r
+  IN EFI_HANDLE Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Connect to this network adapter\r
+  //\r
+  Status = EslServiceConnect ( pThis->DriverBindingHandle,\r
+                               Controller );\r
+\r
+  //\r
+  //  Display the driver start status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and\r
+  closing the DevicePath and PciIo protocols on Controller.\r
+\r
+  @param [in] pThis                Protocol instance pointer.\r
+  @param [in] Controller           Handle of device to stop driver on.\r
+  @param [in] NumberOfChildren     How many children need to be stopped.\r
+  @param [in] pChildHandleBuffer   Not used.\r
+\r
+  @retval EFI_SUCCESS          This driver is removed Controller.\r
+  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.\r
+  @retval other                This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,\r
+  IN  EFI_HANDLE Controller,\r
+  IN  UINTN NumberOfChildren,\r
+  IN  EFI_HANDLE * pChildHandleBuffer\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  \r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Disconnect the network adapters\r
+  //\r
+  Status = EslServiceDisconnect ( pThis->DriverBindingHandle,\r
+                                  Controller );\r
+\r
+  //\r
+  //  Display the driver start status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Driver binding protocol definition\r
+**/\r
+EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {\r
+  DriverSupported,\r
+  DriverStart,\r
+  DriverStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
diff --git a/StdLib/SocketDxe/EntryUnload.c b/StdLib/SocketDxe/EntryUnload.c
new file mode 100644 (file)
index 0000000..6afd8e6
--- /dev/null
@@ -0,0 +1,296 @@
+/** @file\r
+  Implement the entry and unload for the socket driver.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Socket.h"\r
+\r
+\r
+CONST EFI_GUID mEslRawServiceGuid = {\r
+    0xf9f5d280, 0x8a4b, 0x48e2, { 0x96, 0x28, 0xda, 0xfa, 0xa7, 0x70, 0x54, 0x5d }\r
+};\r
+\r
+CONST EFI_GUID mEslTcp4ServiceGuid = {\r
+    0x4dcaab0a, 0x1990, 0x4352, { 0x8d, 0x2f, 0x2d, 0x8f, 0x13, 0x55, 0x98, 0xa5 }\r
+};\r
+\r
+CONST EFI_GUID mEslUdp4ServiceGuid = {\r
+    0x43a110ce, 0x9ccd, 0x402b, { 0x8c, 0x29, 0x4a, 0x6d, 0x8a, 0xf7, 0x79, 0x90 }\r
+};\r
+\r
+\r
+/**\r
+  Socket driver unload routine.\r
+\r
+  @param [in] ImageHandle       Handle for the image.\r
+\r
+  @retval EFI_SUCCESS           Image may be unloaded\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverUnload (\r
+  IN EFI_HANDLE ImageHandle\r
+  )\r
+{\r
+  UINTN BufferSize;\r
+  UINTN Index;\r
+  UINTN Max;\r
+  EFI_HANDLE * pHandle;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Determine which devices are using this driver\r
+  //\r
+  BufferSize = 0;\r
+  pHandle = NULL;\r
+  Status = gBS->LocateHandle (\r
+                  ByProtocol,\r
+                  &gEfiCallerIdGuid,\r
+                  NULL,\r
+                  &BufferSize,\r
+                  NULL );\r
+  if ( EFI_BUFFER_TOO_SMALL == Status ) {\r
+    for ( ; ; ) {\r
+      //\r
+      //  One or more block IO devices are present\r
+      //\r
+      Status = gBS->AllocatePool (\r
+                      EfiRuntimeServicesData,\r
+                      BufferSize,\r
+                      (VOID **) &pHandle\r
+                      );\r
+      if ( EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                  "Insufficient memory, failed handle buffer allocation\r\n" ));\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Locate the block IO devices\r
+      //\r
+      Status = gBS->LocateHandle (\r
+                      ByProtocol,\r
+                      &gEfiCallerIdGuid,\r
+                      NULL,\r
+                      &BufferSize,\r
+                      pHandle );\r
+      if ( EFI_ERROR ( Status )) {\r
+        //\r
+        //  Error getting handles\r
+        //\r
+        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,\r
+                "Failure getting Telnet handles\r\n" ));\r
+        break;\r
+      }\r
+      \r
+      //\r
+      //  Remove any use of the driver\r
+      //\r
+      Max = BufferSize / sizeof ( pHandle[ 0 ]);\r
+      for ( Index = 0; Max > Index; Index++ ) {\r
+        Status = DriverStop ( &gDriverBinding,\r
+                              pHandle[ Index ],\r
+                              0,\r
+                              NULL );\r
+        if ( EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,\r
+                    "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));\r
+          break;\r
+        }\r
+      }\r
+      break;\r
+    }\r
+  }\r
+  else {\r
+    if ( EFI_NOT_FOUND == Status ) {\r
+      //\r
+      //  No devices were found\r
+      //\r
+      Status = EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Free the handle array\r
+  //\r
+  if ( NULL != pHandle ) {\r
+    gBS->FreePool ( pHandle );\r
+  }\r
+\r
+  //\r
+  //  Done with the socket layer\r
+  //\r
+  if ( !EFI_ERROR ( Status )) {\r
+    Status = EslServiceUninstall ( ImageHandle );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Remove the protocols installed by the EntryPoint routine.\r
+      //\r
+      Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  ImageHandle,\r
+                  &gEfiDriverBindingProtocolGuid,\r
+                  &gDriverBinding,\r
+                  &gEfiComponentNameProtocolGuid,\r
+                  &gComponentName,\r
+                  &gEfiComponentName2ProtocolGuid,\r
+                  &gComponentName2,\r
+                  NULL\r
+                  );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",\r
+                ImageHandle ));\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                  "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",\r
+                  ImageHandle ));\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                  "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",\r
+                  ImageHandle ));\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
+                    "ERROR - Failed to remove gEfiDriverBindingProtocolGuid from 0x%08x, Status: %r\r\n",\r
+                    ImageHandle,\r
+                    Status ));\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Disconnect the network services\r
+  //\r
+  if ( !EFI_ERROR ( Status )) {\r
+    EslServiceUnload ( );\r
+  }\r
+\r
+  //\r
+  //  Return the unload status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+Socket driver entry point.\r
+\r
+@param [in] ImageHandle       Handle for the image.\r
+@param [in] pSystemTable      Address of the system table.\r
+\r
+@retval EFI_SUCCESS           Image successfully loaded.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EntryPoint (\r
+  IN EFI_HANDLE ImageHandle,\r
+  IN EFI_SYSTEM_TABLE * pSystemTable\r
+  )\r
+{\r
+  EFI_LOADED_IMAGE_PROTOCOL * pLoadedImage;\r
+  EFI_STATUS    Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Display the image handle\r
+  //\r
+  DEBUG (( DEBUG_INFO,\r
+            "ImageHandle: 0x%08x\r\n",\r
+            ImageHandle ));\r
+\r
+  //\r
+  //  Enable unload support\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  gImageHandle,\r
+                  &gEfiLoadedImageProtocolGuid,\r
+                  (VOID **)&pLoadedImage\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    pLoadedImage->Unload = DriverUnload;\r
+\r
+    //\r
+    //  Add the driver to the list of drivers\r
+    //\r
+    Status = EfiLibInstallDriverBindingComponentName2 (\r
+               ImageHandle,\r
+               pSystemTable,\r
+               &gDriverBinding,\r
+               ImageHandle,\r
+               &gComponentName,\r
+               &gComponentName2\r
+               );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",\r
+                ImageHandle ));\r
+      DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",\r
+                ImageHandle ));\r
+      DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                "Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",\r
+                ImageHandle ));\r
+\r
+      //\r
+      //  Initialize the service layer\r
+      //\r
+      EslServiceLoad ( ImageHandle );\r
+\r
+      //\r
+      //  Make the socket serivces available to other drivers\r
+      //  and applications\r
+      //\r
+      Status = EslServiceInstall ( &ImageHandle );\r
+      if ( EFI_ERROR ( Status )) {\r
+        //\r
+        //  Disconnect from the network\r
+        //\r
+        EslServiceUnload ( );\r
+\r
+        //\r
+        //  Remove the driver bindings\r
+        //\r
+        gBS->UninstallMultipleProtocolInterfaces (\r
+                ImageHandle,\r
+                &gEfiDriverBindingProtocolGuid,\r
+                &gDriverBinding,\r
+                &gEfiComponentNameProtocolGuid,\r
+                &gComponentName,\r
+                &gEfiComponentName2ProtocolGuid,\r
+                &gComponentName2,\r
+                NULL\r
+                );\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",\r
+                ImageHandle ));\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                  "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",\r
+                  ImageHandle ));\r
+        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
+                  "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",\r
+                  ImageHandle ));\r
+      }\r
+    }\r
+    else  {\r
+      DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
+                "ERROR - EfiLibInstallDriverBindingComponentName2 failed, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+  }\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
+PFN_ESL_xSTRUCTOR mpfnEslConstructor = NULL;\r
+PFN_ESL_xSTRUCTOR mpfnEslDestructor = NULL;\r
diff --git a/StdLib/SocketDxe/Socket.h b/StdLib/SocketDxe/Socket.h
new file mode 100644 (file)
index 0000000..dfa4dad
--- /dev/null
@@ -0,0 +1,175 @@
+/** @file\r
+  Definitions for the Socket layer driver.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#ifndef _SOCKET_H_\r
+#define _SOCKET_H_\r
+\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Efi/EfiSocketLib.h>\r
+\r
+#include <Protocol/LoadedImage.h>\r
+\r
+//------------------------------------------------------------------------------\r
+// Protocol Declarations\r
+//------------------------------------------------------------------------------\r
+\r
+extern EFI_COMPONENT_NAME_PROTOCOL gComponentName;    ///<  Component name protocol declaration\r
+extern EFI_COMPONENT_NAME2_PROTOCOL gComponentName2;  ///<  Component name 2 protocol declaration\r
+extern EFI_DRIVER_BINDING_PROTOCOL gDriverBinding;    ///<  Driver binding protocol declaration\r
+extern EFI_SERVICE_BINDING_PROTOCOL mServiceBinding;  ///<  Service binding protocol delcaration\r
+\r
+//------------------------------------------------------------------------------\r
+// Driver Binding Protocol Support\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and\r
+  closing the DevicePath and PciIo protocols on Controller.\r
+\r
+  @param [in] pThis                Protocol instance pointer.\r
+  @param [in] Controller           Handle of device to stop driver on.\r
+  @param [in] NumberOfChildren     How many children need to be stopped.\r
+  @param [in] pChildHandleBuffer   Not used.\r
+\r
+  @retval EFI_SUCCESS          This driver is removed Controller.\r
+  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.\r
+  @retval other                This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,\r
+  IN  EFI_HANDLE Controller,\r
+  IN  UINTN NumberOfChildren,\r
+  IN  EFI_HANDLE * pChildHandleBuffer\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+// EFI Component Name Protocol Support\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 3066 or ISO 639-2 language code format.\r
+  @param [out] ppDriverName     A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,\r
+  IN  CHAR8 * pLanguage,\r
+  OUT CHAR16 ** ppDriverName\r
+  );\r
+\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+  @param [in] ControllerHandle  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+  @param [in] ChildHandle       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 3066 or ISO 639-2 language code format.\r
+  @param [out] ppControllerName A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,\r
+  IN  EFI_HANDLE ControllerHandle,\r
+  IN OPTIONAL EFI_HANDLE ChildHandle,\r
+  IN  CHAR8 * pLanguage,\r
+  OUT CHAR16 ** ppControllerName\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+#endif  //  _SOCKET_H_\r
diff --git a/StdLib/SocketDxe/SocketDxe.inf b/StdLib/SocketDxe/SocketDxe.inf
new file mode 100644 (file)
index 0000000..1b459ba
--- /dev/null
@@ -0,0 +1,62 @@
+#/** @file\r
+# Component description file for the socket layer driver.\r
+#\r
+# This module implements the socket layer.\r
+# Copyright (c) 2011, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SocketDxe\r
+  FILE_GUID                      = 2A43BA5F-AC29-4fdc-8A3B-0328D0256F8C\r
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = EntryPoint\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  Socket.h\r
+  ComponentName.c\r
+  DriverBinding.c\r
+  EntryUnload.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+[LibraryClasses]\r
+  EfiSocketLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  UefiRuntimeLib\r
+  UefiDriverEntryPoint\r
+\r
+[Protocols]\r
+  gEfiTcp4ProtocolGuid\r
+  gEfiTcp4ServiceBindingProtocolGuid\r
+  gEfiUdp4ProtocolGuid\r
+  gEfiUdp4ServiceBindingProtocolGuid\r
+  gEfiSocketProtocolGuid\r
+  gEfiSocketServiceBindingProtocolGuid\r
+\r
+[Depex]\r
+  gEfiBdsArchProtocolGuid AND\r
+  gEfiCpuArchProtocolGuid AND\r
+  gEfiTcp4ServiceBindingProtocolGuid AND\r
+  gEfiTimerArchProtocolGuid AND\r
+  gEfiUdp4ServiceBindingProtocolGuid\r
index 6c5b11aba489c1a7aadaf5e3f9f883d5abd50706..b31469c4a11f8386b955cdf7a25a583dc3aa7b30 100644 (file)
 \r
 [Includes.ARM]\r
   Include/Arm\r
+\r
+\r
+[Guids]\r
+  gStdLibTokenSpaceGuid          = { 0x447559f0, 0xd02e, 0x4cf1, { 0x99, 0xbc, 0xca, 0x11, 0x65, 0x40, 0x54, 0xc2 }}\r
+\r
+\r
+[PcdsFixedAtBuild]\r
+  gStdLibTokenSpaceGuid.DataSource_Port|1234|UINT16|0\r
+  gStdLibTokenSpaceGuid.WebServer_HttpPort|80|UINT16|1\r
+\r
+\r
+[Protocols]\r
+  gEfiSocketProtocolGuid = { 0x58e6ed63, 0x1694, 0x440b, { 0x93, 0x88, 0xe9, 0x8f, 0xed, 0x6b, 0x65, 0xaf } }\r
+  gEfiSocketServiceBindingProtocolGuid = { 0x8aaedb2a, 0xa6bb, 0x47c6, { 0x94, 0xce, 0x1b, 0x80, 0x96, 0x42, 0x3f, 0x2a } }\r
+\r
index 3f71d41e30c8af5a9facfbb2ca1a405a0bb4867e..454f31040ec4b941b6033e58880e570b5061b0d1 100644 (file)
@@ -43,6 +43,7 @@
   #\r
   UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf\r
   ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf\r
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf\r
   #\r
   # Common Libraries\r
   #\r
   ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf\r
   FileHandleLib|ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf\r
   SortLib|ShellPkg/Library/UefiSortLib/UefiSortLib.inf\r
-\r
-  #\r
-  # C Standard Libraries\r
-  #\r
-  LibC|StdLib/LibC/LibC.inf\r
-  LibStdLib|StdLib/LibC/StdLib/StdLib.inf\r
-  LibString|StdLib/LibC/String/String.inf\r
-  LibWchar|StdLib/LibC/Wchar/Wchar.inf\r
-  LibCType|StdLib/LibC/Ctype/Ctype.inf\r
-  LibTime|StdLib/LibC/Time/Time.inf\r
-  LibStdio|StdLib/LibC/Stdio/Stdio.inf\r
-  LibGdtoa|StdLib/LibC/gdtoa/gdtoa.inf\r
-  LibLocale|StdLib/LibC/Locale/Locale.inf\r
-  LibUefi|StdLib/LibC/Uefi/Uefi.inf\r
-  LibMath|StdLib/LibC/Math/Math.inf\r
-  LibSignal|StdLib/LibC/Signal/Signal.inf\r
-  LibNetUtil|StdLib/LibC/NetUtil/NetUtil.inf\r
-\r
-  # Libraries for device abstractions within the Standard C Library\r
-  # Applications should not directly access any functions defined in these libraries.\r
-  DevUtility|StdLib/LibC/Uefi/Devices/daUtility.inf\r
-  DevConsole|StdLib/LibC/Uefi/Devices/daConsole.inf\r
-  DevShell|StdLib/LibC/Uefi/Devices/daShell.inf\r
-\r
-[LibraryClasses.IA32]\r
-  TimerLib|PerformancePkg/Library/DxeTscTimerLib/DxeTscTimerLib.inf\r
-  ## Comment out the above line and un-comment the line below for running under Nt32 emulation.\r
-#  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
-\r
-[LibraryClasses.X64]\r
-  TimerLib|PerformancePkg/Library/DxeTscTimerLib/DxeTscTimerLib.inf\r
-\r
-[LibraryClasses.IPF]\r
-  PalLib|MdePkg/Library/UefiPalLib/UefiPalLib.inf\r
-  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf\r
+  PathLib|ShellPkg/Library/BasePathLib/BasePathLib.inf\r
 \r
 ###################################################################################################\r
 #\r
 ###################################################################################################\r
 \r
 [Components]\r
-# BaseLib and BaseMemoryLib need to be built with the /GL- switch when using the Microsoft\r
-# tool chain.  This is required so that the library functions can be resolved during\r
-# the second pass of the linker during Link-time-code-generation.\r
-###\r
-#  MdePkg/Library/BaseLib/BaseLib.inf {\r
-#    <BuildOptions>\r
-#      MSFT:*_*_*_CC_FLAGS    = /X /Zc:wchar_t /GL-\r
-#  }\r
-#\r
-#  MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf {\r
-#    <BuildOptions>\r
-#      MSFT:*_*_*_CC_FLAGS    = /X /Zc:wchar_t /GL-\r
-#  }\r
-\r
 # Standard C Libraries.\r
   StdLib/LibC/LibC.inf\r
   StdLib/LibC/StdLib/StdLib.inf\r
   StdLib/LibC/Ctype/Ctype.inf\r
   StdLib/LibC/Time/Time.inf\r
   StdLib/LibC/Stdio/Stdio.inf\r
-  StdLib/LibC/gdtoa/gdtoa.inf\r
   StdLib/LibC/Locale/Locale.inf\r
   StdLib/LibC/Uefi/Uefi.inf\r
   StdLib/LibC/Math/Math.inf\r
 \r
 # Device Abstractions within the Standard C Library\r
 # Applications should not directly access any functions defined in these libraries.\r
+  StdLib/LibC/gdtoa/gdtoa.inf\r
   StdLib/LibC/Uefi/Devices/daUtility.inf\r
   StdLib/LibC/Uefi/Devices/daConsole.inf\r
   StdLib/LibC/Uefi/Devices/daShell.inf\r
 \r
-################################################################\r
-#\r
-# See the additional comments below if you plan to run applications under the\r
-# Nt32 emulation environment.\r
-#\r
-\r
-[BuildOptions]\r
-  INTEL:*_*_*_CC_FLAGS          = /Qfreestanding\r
-   MSFT:*_*_*_CC_FLAGS          = /X /Zc:wchar_t\r
-    GCC:*_*_*_CC_FLAGS          = -ffreestanding -nostdinc -nostdlib\r
+# Additional libraries for POSIX functionality.\r
+  StdLib/PosixLib/Err/LibErr.inf\r
+  StdLib/PosixLib/Gen/LibGen.inf\r
+  StdLib/PosixLib/Glob/LibGlob.inf\r
+  StdLib/PosixLib/Stringlist/LibStringlist.inf\r
 \r
-# The Build Options, below, are only used when building the C library\r
-# to be run under the NT32 emulation.  They disable the clock() system call\r
-# which is currently incompatible with the NT32 environment.\r
-# Just uncomment the lines below and select the correct TimerLib instance, above.\r
+#    Socket Applications - LibC based\r
+  StdLib/BsdSocketLib/BsdSocketLib.inf\r
+  StdLib/EfiSocketLib/EfiSocketLib.inf\r
+  StdLib/UseSocketDxe/UseSocketDxe.inf\r
 \r
-  # INTEL:*_*_IA32_CC_FLAGS     = /D NT32dvm\r
-  #  MSFT:*_*_IA32_CC_FLAGS     = /D NT32dvm\r
-  #   GCC:*_*_IA32_CC_FLAGS     = -DNT32dvm\r
+###################################################################################################\r
+#\r
+#       Include Boilerplate text required for building with the Standard Libraries.\r
+#\r
+###################################################################################################\r
+!include StdLib/StdLib.inc\r
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc
new file mode 100644 (file)
index 0000000..e6d1b45
--- /dev/null
@@ -0,0 +1,115 @@
+################################################################\r
+# Boilerplate text to be included by any DSC file using the\r
+# Standard Libraries.\r
+#\r
+# The including DSC file must DEFINE the EMULATE macro if\r
+# the application is to be run in an emulation environment.\r
+################################################################\r
+\r
+##########\r
+#  Socket Support Libraries\r
+##########\r
+\r
+[LibraryClasses.common]\r
+  BsdSocketLib|StdLib/BsdSocketLib/BsdSocketLib.inf\r
+  EfiSocketLib|StdLib/EfiSocketLib/EfiSocketLib.inf\r
+  UseSocketDxe|StdLib/UseSocketDxe/UseSocketDxe.inf\r
+\r
+[LibraryClasses.Common.UEFI_APPLICATION]\r
+  #\r
+  # C Standard Libraries\r
+  #\r
+  LibC|StdLib/LibC/LibC.inf\r
+  LibCType|StdLib/LibC/Ctype/Ctype.inf\r
+  LibLocale|StdLib/LibC/Locale/Locale.inf\r
+  LibMath|StdLib/LibC/Math/Math.inf\r
+  LibSignal|StdLib/LibC/Signal/Signal.inf\r
+  LibStdio|StdLib/LibC/Stdio/Stdio.inf\r
+  LibStdLib|StdLib/LibC/StdLib/StdLib.inf\r
+  LibString|StdLib/LibC/String/String.inf\r
+  LibTime|StdLib/LibC/Time/Time.inf\r
+  LibUefi|StdLib/LibC/Uefi/Uefi.inf\r
+  LibWchar|StdLib/LibC/Wchar/Wchar.inf\r
+\r
+# Common Utilities for Networking Libraries\r
+  LibNetUtil|StdLib/LibC/NetUtil/NetUtil.inf\r
+\r
+# Additional libraries for POSIX functionality.\r
+  LibErr|StdLib/PosixLib/Err/LibErr.inf\r
+  LibGen|StdLib/PosixLib/Gen/LibGen.inf\r
+  LibGlob|StdLib/PosixLib/Glob/LibGlob.inf\r
+  LibStringlist|StdLib/PosixLib/Stringlist/LibStringlist.inf\r
+\r
+# Libraries for device abstractions within the Standard C Library\r
+# Applications should not directly access any functions defined in these libraries.\r
+  LibGdtoa|StdLib/LibC/gdtoa/gdtoa.inf\r
+  DevConsole|StdLib/LibC/Uefi/Devices/daConsole.inf\r
+  DevShell|StdLib/LibC/Uefi/Devices/daShell.inf\r
+  DevUtility|StdLib/LibC/Uefi/Devices/daUtility.inf\r
+\r
+###\r
+# Select the correct TimerLib instance depending upon whether running under\r
+# an emulation environment, or not.\r
+!ifndef $(EMULATE)\r
+  # Not running in an Emulation Environment\r
+[LibraryClasses.IA32.UEFI_APPLICATION]\r
+  TimerLib|PerformancePkg/Library/DxeTscTimerLib/DxeTscTimerLib.inf\r
+\r
+[LibraryClasses.X64.UEFI_APPLICATION]\r
+  TimerLib|PerformancePkg/Library/DxeTscTimerLib/DxeTscTimerLib.inf\r
+\r
+[LibraryClasses.IPF.UEFI_APPLICATION]\r
+  PalLib|MdePkg/Library/UefiPalLib/UefiPalLib.inf\r
+  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf\r
+\r
+!else\r
+  # Running in an Emulation Environment.\r
+  # Adds this to the end of the current [LibraryClasses.Common.UEFI_APPLICATION] section.\r
+[LibraryClasses.Common.UEFI_APPLICATION]\r
+  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
+!endif\r
+\r
+[Components]\r
+# BaseLib and BaseMemoryLib need to be built with the /GL- switch when using the Microsoft\r
+# tool chain.  This is required so that the library functions can be resolved during\r
+# the second pass of the linker during Link-time-code-generation.\r
+###\r
+  MdePkg/Library/BaseLib/BaseLib.inf {\r
+    <BuildOptions>\r
+      MSFT:*_*_*_CC_FLAGS    = /X /Zc:wchar_t /GL-\r
+  }\r
+\r
+  MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf {\r
+    <BuildOptions>\r
+      MSFT:*_*_*_CC_FLAGS    = /X /Zc:wchar_t /GL-\r
+  }\r
+\r
+##########\r
+#  Socket Layer\r
+##########\r
+  StdLib/SocketDxe/SocketDxe.inf\r
+\r
+\r
+##############################################################################\r
+#\r
+# See the additional comments below if you plan to run applications under an\r
+# emulation environment.\r
+#\r
+\r
+[BuildOptions]\r
+!ifndef $(EMULATE)\r
+  # These Build Options are used when building the Standard Libraries to be run\r
+  # on real hardware.\r
+  INTEL:*_*_*_CC_FLAGS      = /Qfreestanding\r
+   MSFT:*_*_*_CC_FLAGS      = /X /Zc:wchar_t\r
+    GCC:*_*_*_CC_FLAGS      = -nostdinc -nostdlib\r
+\r
+!else\r
+  # The Build Options, below, are only used when building the Standard Libraries\r
+  # to be run under an emulation environment.  They disable the clock() system call\r
+  # which is currently incompatible with the most emulation environments.\r
+  # Select the correct TimerLib instance, above.\r
+  INTEL:*_*_IA32_CC_FLAGS     = /Od /D NT32dvm\r
+   MSFT:*_*_IA32_CC_FLAGS     = /Od /D NT32dvm\r
+    GCC:*_*_IA32_CC_FLAGS     = -O0 -DNT32dvm\r
+!endif\r
diff --git a/StdLib/UseSocketDxe/UseSocketDxe.c b/StdLib/UseSocketDxe/UseSocketDxe.c
new file mode 100644 (file)
index 0000000..0b7194c
--- /dev/null
@@ -0,0 +1,160 @@
+/** @file\r
+  Implement the connection to the socket driver\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <Protocol/EfiSocket.h>\r
+#include <Protocol/ServiceBinding.h>\r
+\r
+\r
+/**\r
+  Connect to the socket driver\r
+\r
+  @param [in] ppSocketProtocol  Address to receive the socket protocol address\r
+\r
+  @retval 0             Successfully returned the socket protocol\r
+  @retval other         Value for errno\r
+ **/\r
+int\r
+EslServiceGetProtocol (\r
+  IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol\r
+  )\r
+{\r
+  EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;\r
+  int RetVal;\r
+  EFI_HANDLE SocketHandle;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Locate the socket protocol\r
+  //\r
+  Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,\r
+                                 NULL,\r
+                                 (VOID **)&pServiceBinding );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    //\r
+    //  Create a new socket\r
+    //\r
+    SocketHandle = NULL;\r
+    Status = pServiceBinding->CreateChild ( pServiceBinding,\r
+                                            &SocketHandle );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Get the socket protocol\r
+      //\r
+      Status = gBS->OpenProtocol ( SocketHandle,\r
+                                   &gEfiSocketProtocolGuid,\r
+                                   (VOID **)ppSocketProtocol,\r
+                                   NULL,\r
+                                   NULL,\r
+                                   EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );\r
+      if ( !EFI_ERROR ( Status )) {\r
+        //\r
+        //  Success!\r
+        //\r
+        RetVal = 0;\r
+      }\r
+      else {\r
+        DEBUG (( DEBUG_ERROR,\r
+                  "ERROR - No socket protocol on 0x%08x, Status: %r\r\n",\r
+                  SocketHandle,\r
+                  Status ));\r
+        RetVal = ENODEV;\r
+      }\r
+    }\r
+    else {\r
+      //\r
+      //  Translate the error\r
+      //\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - CreateChild failed, Status: %r\r\n",\r
+                Status ));\r
+      switch ( Status ) {\r
+      case EFI_SUCCESS:\r
+        RetVal = 0;\r
+        break;\r
+\r
+      case EFI_ACCESS_DENIED:\r
+      case EFI_WRITE_PROTECTED:\r
+        RetVal = EACCES;\r
+        break;\r
+\r
+      case EFI_NO_RESPONSE:\r
+        RetVal = EHOSTUNREACH;\r
+        break;\r
+\r
+      case EFI_BAD_BUFFER_SIZE:\r
+      case EFI_BUFFER_TOO_SMALL:\r
+      case EFI_INVALID_PARAMETER:\r
+        RetVal = EINVAL;\r
+        break;\r
+\r
+      case EFI_DEVICE_ERROR:\r
+      case EFI_MEDIA_CHANGED:\r
+      case EFI_NO_MEDIA:\r
+      case EFI_VOLUME_CORRUPTED:\r
+        RetVal = EIO;\r
+        break;\r
+\r
+      case EFI_NOT_FOUND:\r
+        RetVal = ENOENT;\r
+        break;\r
+\r
+      default:\r
+      case EFI_OUT_OF_RESOURCES:\r
+        RetVal = ENOMEM;\r
+        break;\r
+\r
+      case EFI_VOLUME_FULL:\r
+        RetVal = ENOSPC;\r
+        break;\r
+\r
+      case EFI_UNSUPPORTED:\r
+        RetVal = ENOSYS;\r
+        break;\r
+\r
+      case EFI_NO_MAPPING:\r
+        RetVal = ENXIO;\r
+        break;\r
+\r
+      case EFI_LOAD_ERROR:\r
+        RetVal = ESRCH;\r
+        break;\r
+\r
+      case EFI_TIMEOUT:\r
+        RetVal = ETIMEDOUT;\r
+        break;\r
+\r
+      case EFI_NOT_READY:\r
+        RetVal = EWOULDBLOCK;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_ERROR,\r
+              "ERROR - No socket service binding protocol, Status: %r\r\n",\r
+              Status ));\r
+    RetVal = ENODEV;\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return RetVal;\r
+}\r
diff --git a/StdLib/UseSocketDxe/UseSocketDxe.inf b/StdLib/UseSocketDxe/UseSocketDxe.inf
new file mode 100644 (file)
index 0000000..45fb70f
--- /dev/null
@@ -0,0 +1,45 @@
+#/** @file\r
+# Component description file for the EFI socket library.\r
+#\r
+# This module implements the socket layer.\r
+# Copyright (c) 2011, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = UseSocketDxe\r
+  FILE_GUID                      = 1A6853C8-F362-4f68-A77E-0B304A194C05\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = UseSocketDxe\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  UseSocketDxe.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  StdLib/StdLib.dec\r
+#  SocketPkg/SocketPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+\r
+[Protocols]\r
+  gEfiSocketProtocolGuid\r
+  gEfiSocketServiceBindingProtocolGuid\r