home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / ncftp / older_versions / ncftp-3.2.2-src.tar.bz2 / ncftp-3.2.2-src.tar / ncftp-3.2.2 / libncftp / u_decodeurl.c < prev    next >
C/C++ Source or Header  |  2008-07-13  |  6KB  |  243 lines

  1. /* u_decodeurl.c
  2.  *
  3.  * Copyright (c) 1996-2005 Mike Gleason, NcFTP Software.
  4.  * All rights reserved.
  5.  *
  6.  */
  7.  
  8. #include "syshdrs.h"
  9. #ifdef PRAGMA_HDRSTOP
  10. #    pragma hdrstop
  11. #endif
  12.  
  13. #define _CRT_SECURE_NO_WARNINGS 1
  14.  
  15. void
  16. URLCopyToken(char *dst, size_t dsize, const char *src, size_t howmuch)
  17. {
  18.     char *dlim;
  19.     const char *slim;
  20.     unsigned int hc;
  21.     int c;
  22.     char h[4];
  23.  
  24.     dlim = dst + dsize - 1;        /* leave room for \0 */
  25.     slim = src + howmuch;
  26.     while (src < slim) {
  27.         c = *src++;
  28.         if (c == '\0')
  29.             break;
  30.         if (c == '%') {
  31.             /* hex representation */
  32.             if (src < slim + 2) {
  33.                 h[0] = *src++;
  34.                 h[1] = *src++;
  35.                 h[2] = '\0';
  36.                 hc = 0xeeff;
  37.                 if ((sscanf(h, "%x", &hc) >= 0) && (hc != 0xeeff)) {
  38.                     if ((hc == 0) || (hc == '\n') || (hc == '\r') || (hc == /* '\a' */ 0x07) || (hc == /* '\b' */ 0x08) || (hc == /* '\v' */ 0x0B) || (hc == /* '\f' */ 0x0C)) {
  39.                         /* Do not allow these in URLs. */
  40.                         break;
  41.                     }
  42.                     if (dst < dlim) {
  43.                         *(unsigned char *)dst = (unsigned char) hc;
  44.                         dst++;
  45.                     }
  46.                 }
  47.             } else {
  48.                 break;
  49.             }
  50.         } else {
  51.             *dst++ = (char) c;
  52.         }
  53.     }
  54.     *dst = '\0';
  55. }    /* URLCopyToken */
  56.  
  57.  
  58.  
  59.  
  60. int
  61. FTPDecodeURL(
  62.     const FTPCIPtr cip,    /* area pointed to may be modified */
  63.     char *const url,    /* always modified */
  64.     FTPLineListPtr cdlist,    /* always modified */
  65.     char *const fn,        /* always modified */
  66.     const size_t fnsize,
  67.     int *const xtype,    /* optional; may be modified */
  68.     int *const wantnlst    /* optional; always modified */
  69. )
  70. {
  71.     char *cp;
  72.     char *hstart, *hend;
  73.     char *h2start;
  74.     char *at1;
  75.     char portstr[32];
  76.     int port;
  77.     int sc;
  78.     char *lastslash;
  79.     char *parsestr;
  80.     char *tok;
  81.     char subdir[128];
  82.     char *semi;
  83.     char *ctext;
  84.  
  85.     InitLineList(cdlist);
  86.     *fn = '\0';
  87.     if (wantnlst != NULL)
  88.         *wantnlst = 0;
  89.     if (xtype != NULL)
  90.         *xtype = kTypeBinary;
  91.  
  92.     cp = NULL;    /* shut up warnings */
  93. #ifdef HAVE_STRCASECMP
  94.     if (strncasecmp(url, "<URL:ftp://", 11) == 0) {
  95.         cp = url + strlen(url) - 1;
  96.         if (*cp != '>')
  97.             return (kMalformedURL);    /* missing closing > */
  98.         *cp = '\0';
  99.         cp = url + 11;
  100.     } else if (strncasecmp(url, "ftp://", 6) == 0) {
  101.         cp = url + 6;
  102.     } else {
  103.         return (-1);        /* not a RFC 1738 URL */
  104.     }
  105. #else    /* HAVE_STRCASECMP */
  106.     if (strncmp(url, "<URL:ftp://", 11) == 0) {
  107.         cp = url + strlen(url) - 1;
  108.         if (*cp != '>')
  109.             return (kMalformedURL);    /* missing closing > */
  110.         *cp = '\0';
  111.         cp = url + 11;
  112.     } else if (strncmp(url, "ftp://", 6) == 0) {
  113.         cp = url + 6;
  114.     } else {
  115.         return (-1);        /* not a RFC 1738 URL */
  116.     }
  117. #endif    /* HAVE_STRCASECMP */
  118.  
  119.     /* //<user>:<password>@<host>:<port>/<url-path> */
  120.  
  121.     at1 = NULL;
  122.     for (hstart = cp; ; cp++) {
  123.         if (*cp == '@') {
  124.             if (at1 == NULL)
  125.                 at1 = cp;
  126.             else 
  127.                 return (kMalformedURL);
  128.         } else if ((*cp == '\0') || (*cp == '/')) {
  129.             hend = cp;
  130.             break;
  131.         }
  132.     }
  133.  
  134.     sc = *hend;
  135.     *hend = '\0';
  136.     if (at1 == NULL) {
  137.         /* no user or password */
  138.         h2start = hstart;
  139.     } else {
  140.         *at1 = '\0';
  141.         cp = strchr(hstart, ':');
  142.         if (cp == NULL) {
  143.             /* whole thing is the user name then */
  144.             URLCopyToken(cip->user, sizeof(cip->user), hstart, (size_t) (at1 - hstart));
  145.         } else if (strchr(cp + 1, ':') != NULL) {
  146.             /* Too many colons */
  147.             return (kMalformedURL);
  148.         } else {
  149.             URLCopyToken(cip->user, sizeof(cip->user), hstart, (size_t) (cp - hstart));
  150.             URLCopyToken(cip->pass, sizeof(cip->pass), cp + 1, (size_t) (at1 - (cp + 1)));
  151.         }
  152.         *at1 = '@';
  153.         h2start = at1 + 1;
  154.     }
  155.  
  156.     cp = strchr(h2start, ':');
  157.     if (cp == NULL) {
  158.         /* whole thing is the host then */
  159.         URLCopyToken(cip->host, sizeof(cip->host), h2start, (size_t) (hend - h2start));
  160.     } else if (strchr(cp + 1, ':') != NULL) {
  161.         /* Too many colons */
  162.         return (kMalformedURL);
  163.     } else {
  164.         URLCopyToken(cip->host, sizeof(cip->host), h2start, (size_t) (cp - h2start));
  165.         URLCopyToken(portstr, sizeof(portstr), cp + 1, (size_t) (hend - (cp + 1)));
  166.         port = atoi(portstr);
  167.         if (port > 0)
  168.             cip->port = port;
  169.     }
  170.  
  171.     *hend = (char) sc;
  172.     if ((*hend == '\0') || ((*hend == '/') && (hend[1] == '\0'))) {
  173.         /* no path, okay */
  174.         return (0);
  175.     }
  176.  
  177.     lastslash = strrchr(hend, '/');
  178.     if (lastslash == NULL) {
  179.         /* no path, okay */
  180.         return (0);
  181.     }    
  182.     *lastslash = '\0';
  183.  
  184.     if ((semi = strchr(lastslash + 1, ';')) != NULL) {
  185. #ifdef HAVE_STRCASECMP
  186.         if (strcasecmp(semi, ";type=i") == 0) {
  187.             *semi++ = '\0';
  188.             if (xtype != NULL)
  189.                 *xtype = kTypeBinary;
  190.         } else if (strcasecmp(semi, ";type=a") == 0) {
  191.             *semi++ = '\0';
  192.             if (xtype != NULL)
  193.                 *xtype = kTypeAscii;
  194.         } else if (strcasecmp(semi, ";type=b") == 0) {
  195.             *semi++ = '\0';
  196.             if (xtype != NULL)
  197.                 *xtype = kTypeBinary;
  198.         } else if (strcasecmp(semi, ";type=d") == 0) {
  199.             if (wantnlst != NULL) {
  200.                 *semi++ = '\0';
  201.                 *wantnlst = 1;
  202.                 if (xtype != NULL)
  203.                     *xtype = kTypeAscii;
  204.             } else {
  205.                 /* You didn't want these. */
  206.                 return (kMalformedURL);
  207.             }
  208.         }
  209. #else    /* HAVE_STRCASECMP */
  210.         if (strcmp(semi, ";type=i") == 0) {
  211.             *semi++ = '\0';
  212.             if (xtype != NULL)
  213.                 *xtype = kTypeBinary;
  214.         } else if (strcmp(semi, ";type=a") == 0) {
  215.             *semi++ = '\0';
  216.             if (xtype != NULL)
  217.                 *xtype = kTypeAscii;
  218.         } else if (strcmp(semi, ";type=b") == 0) {
  219.             *semi++ = '\0';
  220.             if (xtype != NULL)
  221.                 *xtype = kTypeBinary;
  222.         } else if (strcmp(semi, ";type=d") == 0) {
  223.             if (wantnlst != NULL) {
  224.                 *semi++ = '\0';
  225.                 *wantnlst = 1;
  226.                 if (xtype != NULL)
  227.                     *xtype = kTypeAscii;
  228.             } else {
  229.                 /* You didn't want these. */
  230.                 return (kMalformedURL);
  231.             }
  232.         }
  233. #endif    /* HAVE_STRCASECMP */
  234.     }
  235.     URLCopyToken(fn, fnsize, lastslash + 1, strlen(lastslash + 1));
  236.     for (parsestr = hend, ctext = NULL; (tok = strtokc(parsestr, "/", &ctext)) != NULL; parsestr = NULL) {
  237.         URLCopyToken(subdir, sizeof(subdir), tok, strlen(tok));
  238.         (void) AddLine(cdlist, subdir);
  239.     }
  240.     *lastslash = '/';
  241.     return (kNoErr);
  242. }    /* FTPDecodeURL */
  243.