home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / libncftp / older_versions / libncftp-3.2.2-src.tar.bz2 / libncftp-3.2.2-src.tar / libncftp-3.2.2 / sio / StrAddr.c < prev    next >
C/C++ Source or Header  |  2008-07-13  |  10KB  |  392 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.         errno = 0;
  272.         hp = gethostbyname(hostcp);
  273.         if (hp == NULL) {
  274.             if (errno == 0)
  275.                 errno = ENOENT;
  276.             return (kAddrStrToAddrBadHost);
  277.         }
  278.         sa->sin_family = hp->h_addrtype;
  279.         memcpy(&sa->sin_addr.s_addr, hp->h_addr_list[0],
  280.             (size_t) hp->h_length);
  281.     }
  282.     return (0);
  283. }    /* AddrStrToAddr */
  284.  
  285.  
  286.  
  287.  
  288. char *
  289. AddrToAddrStr(char *const dst, size_t dsize, struct sockaddr_in * const saddrp, int dns, const char *fmt)
  290. {
  291.     char addrName[128];
  292.     char *addrNamePtr;
  293.     struct hostent *hp;
  294.     char str[128];
  295.     char s_name[64];
  296.     char *dlim, *dp;
  297.     const char *cp;
  298.  
  299.     if (dsize == 0)
  300.         return NULL;
  301.     memset(dst, 0, dsize);
  302.  
  303.     addrNamePtr = NULL;
  304.     if (dns == 0) {
  305.         InetNtoA(addrName, &saddrp->sin_addr, sizeof(addrName));
  306.         addrNamePtr = addrName;
  307.     } else {
  308.         hp = gethostbyaddr((gethost_addrptr_t) &saddrp->sin_addr, sizeof(struct in_addr), AF_INET);
  309.         if ((hp != NULL) && (hp->h_name != NULL) && (hp->h_name[0] != '\0')) {
  310.             addrNamePtr = hp->h_name;
  311.         } else {
  312.             InetNtoA(addrName, &saddrp->sin_addr, sizeof(addrName));
  313.             addrNamePtr = addrName;
  314.         }
  315.     }
  316.     if (fmt == NULL)
  317.         fmt = "%h:%p";
  318.     for (dp = dst, dlim = dp + dsize - 1; ; fmt++) {
  319.         if (*fmt == '\0') {
  320.             break;    /* done */
  321.         } else if (*fmt == '%') {
  322.             fmt++;
  323.             if (*fmt == '%') {
  324.                 if (dp < dlim)
  325.                     *dp++ = '%';
  326.             } else if (*fmt == 'p') {
  327.                 sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port));
  328.                 for (cp = str; *cp != '\0'; cp++)
  329.                     if (dp < dlim)
  330.                         *dp++ = *cp;
  331.                 *dp = '\0';
  332.             } else if (*fmt == 'h') {
  333.                 if (addrNamePtr != NULL) {
  334.                     cp = addrNamePtr;
  335.                 } else {
  336.                     cp = "unknown";
  337.                 }
  338.                 for ( ; *cp != '\0'; cp++)
  339.                     if (dp < dlim)
  340.                         *dp++ = *cp;
  341.                 *dp = '\0';
  342.             } else if (*fmt == 's') {
  343.                 cp = s_name;
  344.                 (void) ServicePortNumberToName(ntohs(saddrp->sin_port), s_name, sizeof(s_name), 0);
  345.                 for ( ; *cp != '\0'; cp++)
  346.                     if (dp < dlim)
  347.                         *dp++ = *cp;
  348.                 /* endservent(); */
  349.                 *dp = '\0';
  350.             } else if ((*fmt == 't') || (*fmt == 'u')) {
  351.                 cp = s_name;
  352.                 (void) ServicePortNumberToName(ntohs(saddrp->sin_port), s_name, sizeof(s_name), (int) *fmt);
  353.                 for ( ; *cp != '\0'; cp++)
  354.                     if (dp < dlim)
  355.                         *dp++ = *cp;
  356.                 /* endservent(); */
  357.                 *dp = '\0';
  358.             } else if (*fmt == '\0') {
  359.                 break;
  360.             } else {
  361.                 if (dp < dlim)
  362.                     *dp++ = *fmt;
  363.             }
  364.         } else if (dp < dlim) {
  365.             *dp++ = *fmt;
  366.         }
  367.     }
  368.     *dp = '\0';
  369.     return (dst);
  370. }    /* AddrToAddrStr */
  371.  
  372.  
  373.  
  374.  
  375. char *
  376. AddrStrToIPStr(char *const dst, size_t dsize, const char *const src, const int defaultport)
  377. {
  378.     int rc;
  379.     struct sockaddr_in sa;
  380.  
  381.     if (dsize == 0)
  382.         return NULL;
  383.     memset(dst, 0, dsize);
  384.  
  385.     rc = AddrStrToAddr(src, &sa, (defaultport <= 0) ? 21 : defaultport);
  386.     if (rc < 0)
  387.         return (NULL);
  388.  
  389.     AddrToAddrStr(dst, dsize, &sa, 0, (defaultport <= 0) ? "%h" : "%h:%p");
  390.     return (dst);
  391. }    /* AddrStrToIPStr */
  392.