home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / libncftp / older_versions / libncftp-3.1.5-src.tar.gz / libncftp-3.1.5-src.tar / libncftp-3.1.5 / sio / StrAddr.c < prev    next >
C/C++ Source or Header  |  2002-10-12  |  10KB  |  363 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. #ifndef INADDR_ANY
  7. #    define INADDR_ANY              ((unsigned long int) 0x00000000)
  8. #endif
  9.  
  10. #ifndef INADDR_NONE
  11. #    define INADDR_NONE             ((unsigned long int) 0xffffffff)
  12. #endif
  13.  
  14. /* Linux libc 5.3.x has a bug that causes isalnum() to not work! */
  15. #define ISALNUM(c) ( (((c) >= 'A') && ((c) <= 'Z')) || (((c) >= 'a') && ((c) <= 'z')) || (((c) >= '0') && ((c) <= '9')) )
  16.  
  17. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  18. #    pragma warning(disable : 4711)    // warning: function 'ServiceNameToPortNumber' selected for automatic inline expansion
  19. #endif
  20. unsigned int
  21. ServiceNameToPortNumber(const char *const s, const int proto)
  22. {
  23.     char str[64];
  24.     char *cp;
  25. #if defined(HAVE_GETSERVBYNAME_R) && (defined(AIX) || defined(TRU64UNIX) || defined(DIGITAL_UNIX))
  26.     struct servent *sp;
  27. #elif defined(HAVE_GETSERVBYNAME_R)
  28.     struct servent se, *sp;
  29.     char spbuf[256];
  30. #else
  31.     struct servent *sp;
  32. #endif
  33.     strncpy(str, s, sizeof(str) - 1);
  34.     str[sizeof(str) - 1] = '\0';
  35.     cp = str;
  36.     if (isdigit((int) *cp)) {
  37.         while (isdigit((int) *cp))
  38.             cp++;
  39.         *cp = '\0';
  40.         return (atoi(str));
  41.     }
  42.     for (;; cp++) {
  43.         if ((*cp == '\0')
  44.             || ((!ISALNUM(*cp)) && (*cp != '-') && (*cp != '_')))
  45.                 break;
  46.     }
  47.     *cp = '\0';
  48.  
  49.     sp = NULL;
  50. #if defined(HAVE_GETSERVBYNAME_R) && (defined(SOLARIS) || defined(IRIX) || defined(BSDOS))
  51.     if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
  52.         memset(spbuf, 0, sizeof(spbuf));
  53.         sp = getservbyname_r(str, "tcp", &se, spbuf, sizeof(spbuf));
  54.     }
  55.     if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
  56.         memset(spbuf, 0, sizeof(spbuf));
  57.         sp = getservbyname_r(str, "udp", &se, spbuf, sizeof(spbuf));
  58.     }
  59. #elif defined(HAVE_GETSERVBYNAME_R) && defined(LINUX)
  60.     if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
  61.         memset(spbuf, 0, sizeof(spbuf));
  62.         if (getservbyname_r(str, "tcp", &se, spbuf, sizeof(spbuf), &sp) != 0)
  63.             sp = NULL;
  64.     }
  65.     if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
  66.         memset(spbuf, 0, sizeof(spbuf));
  67.         if (getservbyname_r(str, "udp", &se, spbuf, sizeof(spbuf), &sp) != 0)
  68.             sp = NULL;
  69.     }
  70. #elif defined(HAVE_GETSERVBYNAME_R) && defined(AIX)
  71.     {
  72.         struct servent_data sed;
  73.         if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
  74.             memset(&sed, 0, sizeof(sed));
  75.             if (getservbyname_r(str, "tcp", sp, &sed) != 0)
  76.                 sp = NULL;
  77.         }
  78.         if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
  79.             memset(&sed, 0, sizeof(sed));
  80.             if (getservbyname_r(str, "udp", sp, &sed) != 0)
  81.                 sp = NULL;
  82.         }
  83.     }
  84. #else
  85.     /* Note: getservbyname is already threadsafe on: HP-UX, Tru64 */
  86.     if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
  87.         sp = getservbyname(str, "tcp");
  88.     }
  89.     if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
  90.         sp = getservbyname(str, "udp");
  91.     }
  92. #endif
  93.  
  94.     if (sp != NULL) {
  95.         return ((unsigned int) ntohs((unsigned short) sp->s_port));
  96.     }
  97.     return (0);    /* error */
  98. }    /* ServiceNameToPortNumber */
  99.  
  100.  
  101.  
  102.  
  103. int
  104. ServicePortNumberToName(unsigned short port, char *const dst, const size_t dsize, const int proto)
  105. {
  106. #if defined(HAVE_GETSERVBYNAME_R) && (defined(AIX) || defined(TRU64UNIX) || defined(DIGITAL_UNIX))
  107.     struct servent *sp;
  108. #elif defined(HAVE_GETSERVBYNAME_R)
  109.     struct servent se, *sp;
  110.     char spbuf[256];
  111. #else
  112.     struct servent *sp;
  113. #endif
  114.  
  115.     sp = NULL;
  116. #if defined(HAVE_GETSERVBYPORT_R) && (defined(SOLARIS) || defined(IRIX) || defined(BSDOS))
  117.     if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
  118.         memset(spbuf, 0, sizeof(spbuf));
  119.         sp = getservbyport_r((int) htons(port), "tcp", &se, spbuf, sizeof(spbuf));
  120.     }
  121.     if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
  122.         memset(spbuf, 0, sizeof(spbuf));
  123.         sp = getservbyport_r((int) htons(port), "udp", &se, spbuf, sizeof(spbuf));
  124.     }
  125. #elif defined(HAVE_GETSERVBYPORT_R) && defined(LINUX)
  126.     if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
  127.         memset(spbuf, 0, sizeof(spbuf));
  128.         if (getservbyport_r((int) htons(port), "tcp", &se, spbuf, sizeof(spbuf), &sp) != 0)
  129.             sp = NULL;
  130.     }
  131.     if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
  132.         memset(spbuf, 0, sizeof(spbuf));
  133.         if (getservbyport_r((int) htons(port), "udp", &se, spbuf, sizeof(spbuf), &sp) != 0)
  134.             sp = NULL;
  135.     }
  136. #elif defined(HAVE_GETSERVBYPORT_R) && defined(AIX)
  137.     {
  138.         struct servent_data sed;
  139.         if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
  140.             memset(&sed, 0, sizeof(sed));
  141.             if (getservbyport_r((int) htons(port), "tcp", sp, &sed) != 0)
  142.                 sp = NULL;
  143.         }
  144.         if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
  145.             memset(&sed, 0, sizeof(sed));
  146.             if (getservbyport_r((int) htons(port), "udp", sp, &sed) != 0)
  147.                 sp = NULL;
  148.         }
  149.     }
  150. #else
  151.     /* Note: getservbyport is already threadsafe on: HP-UX, Tru64 */
  152.     if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
  153.         sp = getservbyport((int) htons(port), "tcp");
  154.     }
  155.     if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
  156.         sp = getservbyport((int) htons(port), "ucp");
  157.     }
  158. #endif
  159.  
  160.     if (sp != NULL) {
  161.         strncpy(dst, sp->s_name, dsize);
  162.         dst[dsize - 1] = '\0';
  163.         return (1);
  164.     }
  165.  
  166. #ifdef HAVE_SNPRINTF
  167.     snprintf(dst, dsize,
  168. #else
  169.     sprintf(dst,
  170. #endif
  171.         "%u", (unsigned int) port);
  172.  
  173.     return (0);    /* error */
  174. }    /* ServicePortNumberToName */
  175.  
  176.  
  177.  
  178.  
  179. void
  180. InetNtoA(char *dst, struct in_addr *ia, size_t siz)
  181. {
  182. #if defined(HAVE_INET_NTOP) && !defined(MACOSX)
  183.     /* Mostly to workaround bug in IRIX 6.5's inet_ntoa */
  184.     /* For OS X, don't use inet_ntop yet since it was just introduced
  185.      * for 10.2.
  186.      */
  187.     memset(dst, 0, siz);
  188.     (void) inet_ntop(AF_INET, ia, dst, siz - 1);
  189. #else
  190.     char *cp;
  191.     memset(dst, 0, siz);
  192.     cp = inet_ntoa(*ia);
  193.     if ((cp != (char *) 0) && (cp != (char *) -1) && (cp[0] != '\0')) {
  194.         (void) strncpy(dst, cp, siz - 1);
  195.     }
  196. #endif
  197. }    /* InetNtoA */
  198.  
  199.  
  200.  
  201.  
  202. int
  203. AddrStrToAddr(const char * const s, struct sockaddr_in * const sa, const int defaultport)
  204. {
  205.     char portstr[128];
  206.     unsigned int ipnum;
  207.     unsigned int port;
  208.     struct hostent *hp;
  209.     char *hostcp, *atsign, *colon, *cp, *p2;
  210.  
  211.     memset(sa, 0, sizeof(struct sockaddr_in));
  212.     strncpy(portstr, s, sizeof(portstr));
  213.     portstr[sizeof(portstr) - 1] = '\0';
  214.  
  215.     if ((colon = strchr(portstr, ':')) != NULL) {
  216.         /* Does it look like a URL?  http://host ? */
  217.         if ((colon[1] == '/') && (colon[2] == '/')) {
  218.             *colon = '\0';
  219.             port = 0;
  220.             hostcp = colon + 3;
  221.             for (cp = hostcp; *cp != '\0'; cp++) {
  222.                 if ((!ISALNUM(*cp)) && (*cp != '.')) {
  223.                     /* http://host:port */
  224.                     if ((*cp == ':') && (isdigit((int) cp[1]))) {
  225.                         *cp++ = '\0';
  226.                         p2 = cp;
  227.                         while (isdigit((int) *cp))
  228.                             cp++;
  229.                         *cp = '\0';
  230.                         port = atoi(p2);
  231.                     }
  232.                     *cp = '\0';
  233.                     break;
  234.                 }
  235.             }
  236.             if (port == 0)
  237.                 port = ServiceNameToPortNumber(portstr, 0);
  238.         } else {
  239.             /* Look for host.name.domain:port */
  240.             *colon = '\0';
  241.             hostcp = portstr;
  242.             port = (unsigned int) atoi(colon + 1);
  243.         }
  244.     } else if ((atsign = strchr(portstr, '@')) != NULL) {
  245.         /* Look for port@host.name.domain */
  246.         *atsign = '\0';
  247.         hostcp = atsign + 1;
  248.         port = (unsigned int) atoi(portstr);
  249.     } else if (defaultport > 0) {
  250.         /* Have just host.name.domain, use that w/ default port. */
  251.         port = (unsigned int) defaultport;
  252.         hostcp = portstr;
  253.     } else {
  254.         /* If defaultport <= 0, they must supply a port number
  255.          * in the host/port string.
  256.          */
  257.         errno = EADDRNOTAVAIL;
  258.         return (kAddrStrToAddrMiscErr);
  259.     }
  260.  
  261.     sa->sin_port = htons((short) port);
  262.  
  263.     ipnum = inet_addr(hostcp);
  264.     if (ipnum != INADDR_NONE) {
  265.         sa->sin_family = AF_INET;
  266.         sa->sin_addr.s_addr = ipnum;
  267.     } else {
  268.         errno = 0;
  269.         hp = gethostbyname(hostcp);
  270.         if (hp == NULL) {
  271.             if (errno == 0)
  272.                 errno = ENOENT;
  273.             return (kAddrStrToAddrBadHost);
  274.         }
  275.         sa->sin_family = hp->h_addrtype;
  276.         memcpy(&sa->sin_addr.s_addr, hp->h_addr_list[0],
  277.             (size_t) hp->h_length);
  278.     }
  279.     return (0);
  280. }    /* AddrStrToAddr */
  281.  
  282.  
  283.  
  284. char *
  285. AddrToAddrStr(char *const dst, size_t dsize, struct sockaddr_in * const saddrp, int dns, const char *fmt)
  286. {
  287.     char addrName[128];
  288.     char *addrNamePtr;
  289.     struct hostent *hp;
  290.     char str[128];
  291.     char s_name[64];
  292.     char *dlim, *dp;
  293.     const char *cp;
  294.  
  295.     addrNamePtr = NULL;
  296.     if (dns == 0) {
  297.         InetNtoA(addrName, &saddrp->sin_addr, sizeof(addrName));
  298.         addrNamePtr = addrName;
  299.     } else {
  300.         hp = gethostbyaddr((gethost_addrptr_t) &saddrp->sin_addr, sizeof(struct in_addr), AF_INET);
  301.         if ((hp != NULL) && (hp->h_name != NULL) && (hp->h_name[0] != '\0')) {
  302.             addrNamePtr = hp->h_name;
  303.         } else {
  304.             InetNtoA(addrName, &saddrp->sin_addr, sizeof(addrName));
  305.             addrNamePtr = addrName;
  306.         }
  307.     }
  308.     if (fmt == NULL)
  309.         fmt = "%h:%p";
  310.     for (dp = dst, dlim = dp + dsize - 1; ; fmt++) {
  311.         if (*fmt == '\0') {
  312.             break;    /* done */
  313.         } else if (*fmt == '%') {
  314.             fmt++;
  315.             if (*fmt == '%') {
  316.                 if (dp < dlim)
  317.                     *dp++ = '%';
  318.             } else if (*fmt == 'p') {
  319.                 sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port));
  320.                 for (cp = str; *cp != '\0'; cp++)
  321.                     if (dp < dlim)
  322.                         *dp++ = *cp;
  323.                 *dp = '\0';
  324.             } else if (*fmt == 'h') {
  325.                 if (addrNamePtr != NULL) {
  326.                     cp = addrNamePtr;
  327.                 } else {
  328.                     cp = "unknown";
  329.                 }
  330.                 for ( ; *cp != '\0'; cp++)
  331.                     if (dp < dlim)
  332.                         *dp++ = *cp;
  333.                 *dp = '\0';
  334.             } else if (*fmt == 's') {
  335.                 cp = s_name;
  336.                 (void) ServicePortNumberToName(ntohs(saddrp->sin_port), s_name, sizeof(s_name), 0);
  337.                 for ( ; *cp != '\0'; cp++)
  338.                     if (dp < dlim)
  339.                         *dp++ = *cp;
  340.                 /* endservent(); */
  341.                 *dp = '\0';
  342.             } else if ((*fmt == 't') || (*fmt == 'u')) {
  343.                 cp = s_name;
  344.                 (void) ServicePortNumberToName(ntohs(saddrp->sin_port), s_name, sizeof(s_name), (int) *fmt);
  345.                 for ( ; *cp != '\0'; cp++)
  346.                     if (dp < dlim)
  347.                         *dp++ = *cp;
  348.                 /* endservent(); */
  349.                 *dp = '\0';
  350.             } else if (*fmt == '\0') {
  351.                 break;
  352.             } else {
  353.                 if (dp < dlim)
  354.                     *dp++ = *fmt;
  355.             }
  356.         } else if (dp < dlim) {
  357.             *dp++ = *fmt;
  358.         }
  359.     }
  360.     *dp = '\0';
  361.     return (dst);
  362. }    /* AddrToAddrStr */
  363.