⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filepath.c

📁 apr-1.2.7.tar.gz源码 支持svn的需求
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include "apr.h"#include "apr_private.h"#include "apr_arch_file_io.h"#include "apr_strings.h"#include "apr_lib.h"#include <string.h>#include <ctype.h>#ifdef NETWARE#include <unistd.h>#include <fsio.h>#endif /* WinNT accepts several odd forms of a 'root' path.  Under Unicode * calls (ApiFunctionW) the //?/C:/foo or //?/UNC/mach/share/foo forms * are accepted.  Ansi and Unicode functions both accept the //./C:/foo  * form under WinNT/2K.  Since these forms are handled in the utf-8 to  * unicode translation phase, we don't want the user confused by them, so  * we will accept them but always return the canonical C:/ or //mach/share/ * * OS2 appears immune from the nonsense :) */APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,                                             const char **inpath,                                             apr_int32_t flags,                                            apr_pool_t *p){    const char *testpath = *inpath;    char *newpath;#ifdef NETWARE    char seperator[2] = { 0, 0};    char server[APR_PATH_MAX+1];    char volume[APR_PATH_MAX+1];    char file[APR_PATH_MAX+1];    char *volsep = NULL;    int elements;    if (inpath && *inpath)        volsep = strchr (*inpath, ':');    else        return APR_EBADPATH;    if (strlen(*inpath) > APR_PATH_MAX) {        return APR_EBADPATH;    }    seperator[0] = (flags & APR_FILEPATH_NATIVE) ? '\\' : '/';    /* Allocate and initialize each of the segment buffers    */    server[0] = volume[0] = file[0] = '\0';    /* If we don't have a volume separator then don't bother deconstructing        the path since we won't use the deconstructed information anyway.    */    if (volsep) {        /* Split the inpath into its separate parts. */        deconstruct(testpath, server, volume, NULL, file, NULL, &elements, PATH_UNDEF);            /* If we got a volume part then continue splitting out the root.            Otherwise we either have an incomplete or relative path        */        if (volume && strlen(volume) > 0) {            newpath = apr_pcalloc(p, strlen(server)+strlen(volume)+5);            construct(newpath, server, volume, NULL, NULL, NULL, PATH_NETWARE);            /* NetWare doesn't add the root slash so we need to add it manually.            */            strcat(newpath, seperator);            *rootpath = newpath;            /* Skip the inpath pointer down to the first non-root character            */            newpath = volsep;            do {                ++newpath;            } while (*newpath && ((*newpath == '/') || (*newpath == '\\')));            *inpath = newpath;            /* Need to handle APR_FILEPATH_TRUENAME checking here. */            return APR_SUCCESS;        }        else            return APR_EBADPATH;    }    else if ((**inpath == '/') || (**inpath == '\\')) {        /* if we have a root path without a volume then just split            in same manner as unix although this path will be            incomplete.        */        *rootpath = apr_pstrdup(p, seperator);        do {            ++(*inpath);        } while ((**inpath == '/') || (**inpath == '\\'));    }    else        return APR_ERELATIVE;    return APR_EINCOMPLETE;#else /* ndef(NETWARE) */    char seperator[2];    const char *delim1;    const char *delim2;    seperator[0] = (flags & APR_FILEPATH_NATIVE) ? '\\' : '/';    seperator[1] = 0;    if (testpath[0] == '/' || testpath[0] == '\\') {        if (testpath[1] == '/' || testpath[1] == '\\') {#ifdef WIN32 /* //server/share isn't the only // delimited syntax */            if ((testpath[2] == '?' || testpath[2] == '.')                    && (testpath[3] == '/' || testpath[3] == '\\')) {                if (IS_FNCHAR(testpath[4]) && testpath[5] == ':')                 {                    apr_status_t rv;                    testpath += 4;                    /* given  '//?/C: or //./C: let us try this                     * all over again from the drive designator                     */                    rv = apr_filepath_root(rootpath, &testpath, flags, p);                    if (!rv || rv == APR_EINCOMPLETE)                        *inpath = testpath;                    return rv;                }                else if (strncasecmp(testpath + 4, "UNC", 3) == 0                      && (testpath[7] == '/' || testpath[7] == '\\')                       && (testpath[2] == '?')) {                    /* given  '//?/UNC/machine/share, a little magic                      * at the end makes this all work out by using                     * 'C/machine' as the starting point and replacing                     * the UNC delimiters with \'s, including the 'C'                     */                    testpath += 6;                }                else                    /* This must not be a path to a file, but rather                     * a volume or device.  Die for now.                     */                    return APR_EBADPATH;            }#endif /* WIN32 (non - //server/share syntax) */            /* Evaluate path of '//[machine/[share[/]]]' */            delim1 = testpath + 2;            do {                /* Protect against //X/ where X is illegal */                if (*delim1 && !IS_FNCHAR(*(delim1++)))                    return APR_EBADPATH;            } while (*delim1 && *delim1 != '/' && *delim1 != '\\');            if (*delim1) {                apr_status_t rv;                delim2 = delim1 + 1;                while (*delim2 && *delim2 != '/' && *delim2 != '\\') {                    /* Protect against //machine/X/ where X is illegal */                    if (!IS_FNCHAR(*(delim2++)))                        return APR_EBADPATH;                }                 /* Copy the '//machine/[share[/]]' path, always providing                  * an extra byte for the trailing slash.                 */                newpath = apr_pstrmemdup(p, testpath, delim2 - testpath + 1);                if (delim2 == delim1 + 1) {                    /* We found simply \\machine\, so give up already                     */                    *rootpath = newpath;                    *inpath = delim2;                    return APR_EINCOMPLETE;                }                if (flags & APR_FILEPATH_TRUENAME) {                    /* Validate the \\Machine\Share\ designation,                      * Win32 will argue about slashed in UNC paths,                      * so use backslashes till we finish testing,                     * and add the trailing backslash [required].                     * apr_pstrmemdup above guarentees us the new                      * trailing null character.                     */                    newpath[0] = '\\';                    newpath[1] = '\\';                    newpath[delim1 - testpath] = '\\';                    newpath[delim2 - testpath] = '\\';                    rv = filepath_root_test(newpath, p);                    if (rv)                        return rv;                    rv = filepath_root_case(&newpath, newpath, p);                    if (rv)                        return rv;                    newpath[0] = seperator[0];                    newpath[1] = seperator[0];                    newpath[delim1 - testpath] = seperator[0];                    newpath[delim2 - testpath] = (*delim2 ? seperator[0] : '\0');                }                else {                                    /* Give back the caller's own choice of delimiters                     */                    newpath[0] = testpath[0];                    newpath[1] = testpath[1];                    newpath[delim1 - testpath] = *delim1;                    newpath[delim2 - testpath] = *delim2;                }                /* If this root included the trailing / or \ designation                  * then lop off multiple trailing slashes and give back                 * appropriate delimiters.                 */                if (*delim2) {                    *inpath = delim2 + 1;                    while (**inpath == '/' || **inpath == '\\')                        ++*inpath;                }                else {                    *inpath = delim2;                }                *rootpath = newpath;                return APR_SUCCESS;            }                        /* Have path of '\\[machine]', if the machine is given,             * append same trailing slash as the leading slash             */            delim1 = strchr(testpath, '\0');            if (delim1 > testpath + 2) {                newpath = apr_pstrndup(p, testpath, delim1 - testpath + 1);                if (flags & APR_FILEPATH_TRUENAME)                    newpath[delim1 - testpath] = seperator[0];                else                    newpath[delim1 - testpath] = newpath[0];                newpath[delim1 - testpath + 1] = '\0';            }            else {                newpath = apr_pstrndup(p, testpath, delim1 - testpath);            }            if (flags & APR_FILEPATH_TRUENAME) {                newpath[0] = seperator[0];                newpath[1] = seperator[0];            }            *rootpath = newpath;            *inpath = delim1;            return APR_EINCOMPLETE;        }        /* Left with a path of '/', what drive are we asking about?          */        *inpath = testpath + 1;        newpath = apr_palloc(p, 2);        if (flags & APR_FILEPATH_TRUENAME)            newpath[0] = seperator[0];        else            newpath[0] = testpath[0];        newpath[1] = '\0';        *rootpath = newpath;        return APR_EINCOMPLETE;    }    /* Evaluate path of 'd:[/]' */    if (IS_FNCHAR(*testpath) && testpath[1] == ':')     {        apr_status_t rv;        /* Validate that D:\ drive exists, test must be rooted         * Note that posix/win32 insists a drive letter is upper case,         * so who are we to argue with a 'feature'.         * It is a safe fold, since only A-Z is legal, and has no         * side effects of legal mis-mapped non-us-ascii codes.         */        newpath = apr_palloc(p, 4);        newpath[0] = testpath[0];        newpath[1] = testpath[1];        newpath[2] = seperator[0];        newpath[3] = '\0';        if (flags & APR_FILEPATH_TRUENAME) {            newpath[0] = apr_toupper(newpath[0]);            rv = filepath_root_test(newpath, p);            if (rv)                return rv;        }        /* Just give back the root the user handed to us.         */        if (testpath[2] != '/' && testpath[2] != '\\') {            newpath[2] = '\0';            *rootpath = newpath;            *inpath = testpath + 2;            return APR_EINCOMPLETE;        }        /* strip off remaining slashes that designate the root,         * give the caller back their original choice of slash         * unless this is TRUENAME'ed         */        *inpath = testpath + 3;        while (**inpath == '/' || **inpath == '\\')            ++*inpath;        if (!(flags & APR_FILEPATH_TRUENAME))            newpath[2] = testpath[2];        *rootpath = newpath;        return APR_SUCCESS;    }    /* Nothing interesting */    return APR_ERELATIVE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -