home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume39 / tcp_wrappers / part04 / workarounds.c < prev   
Encoding:
C/C++ Source or Header  |  1993-09-29  |  3.7 KB  |  161 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.1 93/09/21 23:16:38";
  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. #include "log_tcp.h"
  24.  
  25.  /*
  26.   * Some DG/UX inet_addr() versions return a struct/union instead of a long.
  27.   * You have this problem when the compiler complains about illegal lvalues
  28.   * or something like that. The following code fixes this mutant behaviour.
  29.   * It should not be enabled on "normal" systems.
  30.   * 
  31.   * Bug reported by ben@piglet.cr.usgs.gov (Rev. Ben A. Mesander).
  32.   */
  33.  
  34. #ifdef INET_ADDR_BUG
  35.  
  36. #undef inet_addr
  37.  
  38. long    fix_inet_addr(string)
  39. char   *string;
  40. {
  41.     return (inet_addr(string).s_addr);
  42. }
  43.  
  44. #endif /* INET_ADDR_BUG */
  45.  
  46.  /*
  47.   * With some System-V versions, the fgets() library function does not
  48.   * account for partial reads from e.g. sockets. The result is that fgets()
  49.   * gives up too soon, causing username lookups to fail. Problem first
  50.   * reported for IRIX 4.0.5, by Steve Kotsopoulos <steve@ecf.toronto.edu>.
  51.   * The following code works around the problem. It does no harm on "normal"
  52.   * systems.
  53.   */
  54.  
  55. #ifdef BROKEN_FGETS
  56.  
  57. #undef fgets
  58.  
  59. char   *fix_fgets(buf, len, fp)
  60. char   *buf;
  61. int     len;
  62. FILE   *fp;
  63. {
  64.     char   *cp = buf;
  65.     int     c;
  66.  
  67.     /*
  68.      * Copy until the buffer fills up, until EOF, or until a newline is
  69.      * found.
  70.      */
  71.     while (len > 1 && (c = getc(fp)) != EOF) {
  72.     len--;
  73.     *cp++ = c;
  74.     if (c == '\n')
  75.         break;
  76.     }
  77.  
  78.     /*
  79.      * Return 0 if nothing was read. This is correct even when a silly buffer
  80.      * length was specified.
  81.      */
  82.     if (cp > buf) {
  83.     *cp = 0;
  84.     return (buf);
  85.     } else {
  86.     return (0);
  87.     }
  88. }
  89.  
  90. #endif /* BROKEN_FGETS */
  91.  
  92.  /*
  93.   * With early SunOS 5 versions, recvfrom() does not completely fill in the
  94.   * source address structure when doing a non-destructive read. The following
  95.   * code works around the problem. It does no harm on "normal" systems.
  96.   */
  97.  
  98. #ifdef RECVFROM_BUG
  99.  
  100. #undef recvfrom
  101.  
  102. int     fix_recvfrom(sock, buf, buflen, flags, from, fromlen)
  103. int     sock;
  104. char   *buf;
  105. int     buflen;
  106. int     flags;
  107. struct sockaddr *from;
  108. int    *fromlen;
  109. {
  110.     int     ret;
  111.  
  112.     /* Assume that both ends of a socket belong to the same address family. */
  113.  
  114.     if ((ret = recvfrom(sock, buf, buflen, flags, from, fromlen)) >= 0) {
  115.     if (from->sa_family == 0) {
  116.         struct sockaddr my_addr;
  117.         int     my_addr_len = sizeof(my_addr);
  118.  
  119.         if (getsockname(0, &my_addr, &my_addr_len)) {
  120.         syslog(LOG_ERR, "getsockname: %m");
  121.         } else {
  122.         from->sa_family = my_addr.sa_family;
  123.         }
  124.     }
  125.     }
  126.     return (ret);
  127. }
  128.  
  129. #endif /* RECVFROM_BUG */
  130.  
  131.  /*
  132.   * The Apollo SR10.3 and some SYSV4 getpeername(2) versions do not return an
  133.   * error in case of a datagram-oriented socket. Instead, they claim that all
  134.   * UDP requests come from address 0.0.0.0. The following code works around
  135.   * the problem. It does no harm on "normal" systems.
  136.   */
  137.  
  138. #ifdef GETPEERNAME_BUG
  139.  
  140. #undef getpeername
  141.  
  142. int     fix_getpeername(sock, sa, len)
  143. int     sock;
  144. struct sockaddr *sa;
  145. int    *len;
  146. {
  147.     int     ret;
  148.     struct sockaddr_in *sin = (struct sockaddr_in *) sa;
  149.  
  150.     if ((ret = getpeername(sock, sa, len)) >= 0
  151.     && sa->sa_family == AF_INET
  152.     && sin->sin_addr.s_addr == 0) {
  153.     errno = ENOTCONN;
  154.     return (-1);
  155.     } else {
  156.     return (ret);
  157.     }
  158. }
  159.  
  160. #endif /* GETPEERNAME_BUG */
  161.