home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / libncftp / libncftp-3.2.5-src.zip / libncftp-3.2.5 / sio / StrAddr.c < prev    next >
C/C++ Source or Header  |  2009-10-23  |  11KB  |  407 lines

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