apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject cvs commit: apr/file_io/win32 filepath.c
Date Mon, 27 Aug 2001 20:02:31 GMT
wrowe       01/08/27 13:02:31

  Modified:    file_io/win32 filepath.c
  Log:
    Here is the near-completion of APR_FILEPATH_TRUENAME for Win32.  It really
    needs a richer error reporting and 'additional path info' mechanism,
    I believe.  Right now we simply stop parsing at a /path/file/more
    situation and return the /more string as given.  This would be fine for
    /path/dir/more where more doesn't exist, but it's a little obscure for
    the /path/file/more example.  Comments are welcome, especially from the
    OS2/Netware/OS-X folks who need similar behavior.
  
  Revision  Changes    Path
  1.8       +110 -18   apr/file_io/win32/filepath.c
  
  Index: filepath.c
  ===================================================================
  RCS file: /home/cvs/apr/file_io/win32/filepath.c,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- filepath.c	2001/06/27 19:44:23	1.7
  +++ filepath.c	2001/08/27 20:02:31	1.8
  @@ -757,8 +757,9 @@
           }
           else if (seglen == 2 && addpath[0] == '.' && addpath[1] == '.')

           {
  -            /* NOTE: win32 _hates_ '/.. /' (yes, with a space in there) and
  -             * '/..../' so eliminate all preconceptions that they are valid.
  +            /* NOTE: win32 _hates_ '/.. /' (yes, with a space in there)
  +             * and '/..../', some functions treat it as ".", and some 
  +             * fail! Eliminate all preconceptions that they are valid.
                */
               if (seglen < segend && (seglen != 3 || addpath[2] != '.'))
                   return APR_EBADPATH;
  @@ -830,7 +831,6 @@
                   apr_status_t testtype;
                   apr_size_t i = (addpath[segend] != '\0');
                   
  -
                   /* This isn't legal unless the unc path is complete!
                    */
                   if (seglen < segend)
  @@ -886,7 +886,6 @@
   
           addpath += segend;
       }
  -    path[pathlen] = '\0';
       
       /* keptlen will be the baselen unless the addpath contained
        * backpath elements.  If so, and APR_FILEPATH_NOTABOVEROOT
  @@ -896,7 +895,7 @@
        * segment is thoroughly tested prior to path parsing.
        */
       if (flags & APR_FILEPATH_NOTABOVEROOT && (keptlen - rootlen) < baselen)
{
  -        if (strncmp(basepath, path + rootlen, baselen))
  +        if (memcmp(basepath, path + rootlen, baselen))
               return APR_EABOVEROOT;
   
           /* Ahem... if we weren't given a trailing slash on the basepath,
  @@ -908,22 +907,115 @@
               return APR_EABOVEROOT;
       }
   
  -#if 0
  -    /* Just an idea - still don't know where it's headed */
  -    if (addpath && addpath[endseg - 1] != '/' 
  -                && (flags & APR_FILEPATH_TRUECASE)) {
  -        apr_finfo_t finfo;
  -        if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) == APR_SUCCESS) {
  -            if (addpath[endseg - 1] != finfo.filetype == APR_DIR) {
  -                if (endseg + 1 >= sizeof(path))
  -                    return APR_ENAMETOOLONG;
  -                path[endseg++] = '/';
  -                path[endseg] = '\0';
  +    if (addpath && (flags & APR_FILEPATH_TRUENAME)) {
  +        /* We can always skip the root, it's already true-named. */
  +        if (rootlen > keptlen)
  +            keptlen = rootlen;
  +        if ((path[keptlen] == '/') || (path[keptlen] == '\\')) {
  +            /* By rights, keptlen may grown longer than pathlen.
  +             * we wont' use it again (in that case) so we don't care.
  +             */
  +            ++keptlen;
  +        }
  +        /* Go through all the new segments */
  +        while (keptlen < pathlen) {
  +            apr_finfo_t finfo;
  +            char saveslash = 0;
  +            seglen = 0;
  +            /* find any slash and set it aside for a minute. */
  +            for (seglen = 0; keptlen + seglen < pathlen; ++seglen) {
  +                if ((path[keptlen + seglen] == '/')  ||
  +                    (path[keptlen + seglen] == '\\')) {
  +                    saveslash = path[keptlen + seglen];
  +                    break;
  +                }
               }
  +            /* Null term for stat! */
  +            path[keptlen + seglen] = '\0';
  +            if ((rv = apr_stat(&finfo, path, APR_FINFO_TYPE | APR_FINFO_NAME, p))
  +                    == APR_SUCCESS) {
  +                size_t namelen = strlen(finfo.name);
  +                if ((namelen != seglen) || 
  +                    (memcmp(finfo.name, path + keptlen, seglen) != 0)) 
  +                {
  +                    if (namelen <= seglen) {
  +                        memcpy(path + keptlen, finfo.name, namelen);
  +                        if ((namelen < seglen) && saveslash) {
  +                            memmove(path + keptlen + namelen + 1,
  +                                   path + keptlen + seglen + 1,
  +                                   pathlen - keptlen - seglen);
  +                            pathlen += namelen - seglen;
  +                            seglen = namelen;
  +                        }
  +                    }
  +                    else { /* namelen > seglen */
  +                        if (pathlen + namelen - seglen >= sizeof(path))
  +                            return APR_ENAMETOOLONG;
  +                        if ((namelen < seglen) && saveslash) {
  +                            memmove(path + keptlen + namelen + 1,
  +                                   path + keptlen + seglen + 1,
  +                                   pathlen - keptlen - seglen);
  +                        }
  +                        memcpy(path + keptlen, finfo.name, namelen);
  +                        pathlen += namelen - seglen;
  +                        seglen = namelen;
  +                    }
  +                }
  +                /* That's it, the rest is path info. 
  +                 * I don't know how we aught to handle this.  Should
  +                 * we define a new error to indicate 'more info'?
  +                 * Should we split out the rest of the path?
  +                 */
  +                if ((finfo.filetype != APR_DIR) && 
  +                    (finfo.filetype != APR_LNK) && saveslash) 
  +                    rv = APR_ENOTDIR;
  +#ifdef XXX_FIGURE_THIS_OUT
  +                {
  +                    /* the example inserts a null between the end of 
  +                     * the filename and the next segment, and increments
  +                     * the path length so we would return both segments.
  +                     */
  +                    if (saveslash) {
  +                        keptlen += seglen;
  +                        path[keptlen] = saveslash;
  +                        if (pathlen + 1 >= sizeof(path))
  +                            return APR_ENAMETOOLONG;
  +                        memmove(path + keptlen + 1,
  +                               path + keptlen,
  +                               pathlen - keptlen);
  +                        path[keptlen] = '\0';
  +                        ++pathlen;
  +                        break;
  +                    }
  +                }
  +#endif
  +            }
  +
  +            /* put back the '/' */
  +            if (saveslash) {
  +                path[keptlen + seglen] = saveslash;
  +                ++seglen;
  +            }
  +            keptlen += seglen;
  +
  +            if (rv != APR_SUCCESS) {
  +                if (APR_STATUS_IS_ENOENT(rv))
  +                    break;
  +                else if (APR_STATUS_IS_ENOENT(rv))
  +                    /* This is a little more serious, we just added a name
  +                     * onto a filename (think http's CGI MORE_INFO)
  +                     * If the caller is foolish enough to do this, we expect
  +                     * the've already canonicalized the root) that they knew
  +                     * what they are doing :(
  +                     */
  +                    break;
  +                else
  +                    return rv;
  +            }
           }
       }
  -#endif
   
  -    *newpath = apr_pstrdup(p, path);
  +    *newpath = apr_pmemdup(p, path, pathlen + 1);
  +    (*newpath)[pathlen] = '\0';
       return APR_SUCCESS;
   }
  
  
  

Mime
View raw message