home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / tcp_wrapper-6.3 / workarounds.c < prev   
Encoding:
C/C++ Source or Header  |  1994-03-27  |  4.5 KB  |  199 lines

  1.  /*
  2.   * Workarounds for known system software bugs. This module provides wrappers
  3.   * around library functions and system calls that are known to have problems
  4.   * on some systems. Most of these workarounds won't do any harm on regular
  5.   * systems.
  6.   * 
  7.   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  8.   */
  9.  
  10. #ifndef lint
  11. char    sccsid[] = "@(#) workarounds.c 1.2 94/02/01 22:12:23";
  12. #endif
  13.  
  14. #include <sys/types.h>
  15. #include <sys/param.h>
  16. #include <sys/socket.h>
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19. #include <errno.h>
  20. #include <stdio.h>
  21. #include <syslog.h>
  22.  
  23. extern int errno;
  24.  
  25. #include "log_tcp.h"
  26.  
  27.  /*
  28.   * Some AIX versions advertise a too small MAXHOSTNAMELEN value (32).
  29.   * Result: long hostnames would be truncated, and connections would be
  30.   * dropped because of host name verification failures. Adrian van Bloois
  31.   * (A.vanBloois@info.nic.surfnet.nl) figured out what was the problem.
  32.   */
  33.  
  34. #if (MAXHOSTNAMELEN < 64)
  35. #undef MAXHOSTNAMELEN
  36. #endif
  37.  
  38. /* In case not defined in <sys/param.h>. */
  39.  
  40. #ifndef MAXHOSTNAMELEN
  41. #define MAXHOSTNAMELEN  256             /* storage for host name */
  42. #endif
  43.  
  44.  /*
  45.   * Some DG/UX inet_addr() versions return a struct/union instead of a long.
  46.   * You have this problem when the compiler complains about illegal lvalues
  47.   * or something like that. The following code fixes this mutant behaviour.
  48.   * It should not be enabled on "normal" systems.
  49.   * 
  50.   * Bug reported by ben@piglet.cr.usgs.gov (Rev. Ben A. Mesander).
  51.   */
  52.  
  53. #ifdef INET_ADDR_BUG
  54.  
  55. #undef inet_addr
  56.  
  57. long    fix_inet_addr(string)
  58. char   *string;
  59. {
  60.     return (inet_addr(string).s_addr);
  61. }
  62.  
  63. #endif /* INET_ADDR_BUG */
  64.  
  65.  /*
  66.   * With some System-V versions, the fgets() library function does not
  67.   * account for partial reads from e.g. sockets. The result is that fgets()
  68.   * gives up too soon, causing username lookups to fail. Problem first
  69.   * reported for IRIX 4.0.5, by Steve Kotsopoulos <steve@ecf.toronto.edu>.
  70.   * The following code works around the problem. It does no harm on "normal"
  71.   * systems.
  72.   */
  73.  
  74. #ifdef BROKEN_FGETS
  75.  
  76. #undef fgets
  77.  
  78. char   *fix_fgets(buf, len, fp)
  79. char   *buf;
  80. int     len;
  81. FILE   *fp;
  82. {
  83.     char   *cp = buf;
  84.     int     c;
  85.  
  86.     /*
  87.      * Copy until the buffer fills up, until EOF, or until a newline is
  88.      * found.
  89.      */
  90.     while (len > 1 && (c = getc(fp)) != EOF) {
  91.     len--;
  92.     *cp++ = c;
  93.     if (c == '\n')
  94.         break;
  95.     }
  96.  
  97.     /*
  98.      * Return 0 if nothing was read. This is correct even when a silly buffer
  99.      * length was specified.
  100.      */
  101.     if (cp > buf) {
  102.     *cp = 0;
  103.     return (buf);
  104.     } else {
  105.     return (0);
  106.     }
  107. }
  108.  
  109. #endif /* BROKEN_FGETS */
  110.  
  111.  /*
  112.   * With early SunOS 5 versions, recvfrom() does not completely fill in the
  113.   * source address structure when doing a non-destructive read. The following
  114.   * code works around the problem. It does no harm on "normal" systems.
  115.   */
  116.  
  117. #ifdef RECVFROM_BUG
  118.  
  119. #undef recvfrom
  120.  
  121. int     fix_recvfrom(sock, buf, buflen, flags, from, fromlen)
  122. int     sock;
  123. char   *buf;
  124. int     buflen;
  125. int     flags;
  126. struct sockaddr *from;
  127. int    *fromlen;
  128. {
  129.     int     ret;
  130.  
  131.     /* Assume that both ends of a socket belong to the same address family. */
  132.  
  133.     if ((ret = recvfrom(sock, buf, buflen, flags, from, fromlen)) >= 0) {
  134.     if (from->sa_family == 0) {
  135.         struct sockaddr my_addr;
  136.         int     my_addr_len = sizeof(my_addr);
  137.  
  138.         if (getsockname(0, &my_addr, &my_addr_len)) {
  139.         syslog(LOG_ERR, "getsockname: %m");
  140.         } else {
  141.         from->sa_family = my_addr.sa_family;
  142.         }
  143.     }
  144.     }
  145.     return (ret);
  146. }
  147.  
  148. #endif /* RECVFROM_BUG */
  149.  
  150.  /*
  151.   * The Apollo SR10.3 and some SYSV4 getpeername(2) versions do not return an
  152.   * error in case of a datagram-oriented socket. Instead, they claim that all
  153.   * UDP requests come from address 0.0.0.0. The following code works around
  154.   * the problem. It does no harm on "normal" systems.
  155.   */
  156.  
  157. #ifdef GETPEERNAME_BUG
  158.  
  159. #undef getpeername
  160.  
  161. int     fix_getpeername(sock, sa, len)
  162. int     sock;
  163. struct sockaddr *sa;
  164. int    *len;
  165. {
  166.     int     ret;
  167.     struct sockaddr_in *sin = (struct sockaddr_in *) sa;
  168.  
  169.     if ((ret = getpeername(sock, sa, len)) >= 0
  170.     && sa->sa_family == AF_INET
  171.     && sin->sin_addr.s_addr == 0) {
  172.     errno = ENOTCONN;
  173.     return (-1);
  174.     } else {
  175.     return (ret);
  176.     }
  177. }
  178.  
  179. #endif /* GETPEERNAME_BUG */
  180.  
  181.  /*
  182.   * According to Karl Vogel (vogelke@c-17igp.wpafb.af.mil) some Pyramid
  183.   * versions have no yp_default_domain() function. We use getdomainname()
  184.   * instead.
  185.   */
  186.  
  187. #ifdef USE_GETDOMAIN
  188.  
  189. int     yp_get_default_domain(ptr)
  190. char  **ptr;
  191. {
  192.     static char mydomain[MAXHOSTNAMELEN];
  193.  
  194.     *ptr = mydomain;
  195.     return (getdomainname(mydomain, MAXHOSTNAMELEN));
  196. }
  197.  
  198. #endif /* USE_GETDOMAIN */
  199.