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

📄 filepath.c

📁 apr-1.2.7.tar.gz源码 支持svn的需求
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif /* ndef(NETWARE) */}APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,                                              const char *basepath,                                              const char *addpath,                                              apr_int32_t flags,                                             apr_pool_t *p){    char path[APR_PATH_MAX]; /* isn't null term */    const char *baseroot = NULL;    const char *addroot;    apr_size_t rootlen; /* the length of the root portion of path, d:/ is 3 */    apr_size_t baselen; /* the length of basepath (excluding baseroot) */    apr_size_t keptlen; /* the length of the retained basepath (incl root) */    apr_size_t pathlen; /* the length of the result path */    apr_size_t segend;  /* the end of the current segment */    apr_size_t seglen;  /* the length of the segment (excl trailing chars) */    apr_status_t basetype = 0; /* from parsing the basepath's baseroot */    apr_status_t addtype;      /* from parsing the addpath's addroot */    apr_status_t rv;#ifndef NETWARE    int fixunc = 0;  /* flag to complete an incomplete UNC basepath */#endif        /* Treat null as an empty path, otherwise split addroot from the addpath     */    if (!addpath) {        addpath = addroot = "";        addtype = APR_ERELATIVE;    }    else {        /* This call _should_ test the path         */        addtype = apr_filepath_root(&addroot, &addpath,                                     APR_FILEPATH_TRUENAME                                    | (flags & APR_FILEPATH_NATIVE),                                    p);        if (addtype == APR_SUCCESS) {            addtype = APR_EABSOLUTE;        }        else if (addtype == APR_ERELATIVE) {            addroot = "";        }        else if (addtype != APR_EINCOMPLETE) {            /* apr_filepath_root was incomprehensible so fail already             */            return addtype;        }    }    /* If addpath is (even partially) rooted, then basepath is     * unused.  Ths violates any APR_FILEPATH_SECUREROOTTEST      * and APR_FILEPATH_NOTABSOLUTE flags specified.     */    if (addtype == APR_EABSOLUTE || addtype == APR_EINCOMPLETE)    {        if (flags & APR_FILEPATH_SECUREROOTTEST)            return APR_EABOVEROOT;        if (flags & APR_FILEPATH_NOTABSOLUTE)            return addtype;    }    /* Optimized tests before we query the current working path     */    if (!basepath) {        /* If APR_FILEPATH_NOTABOVEROOT wasn't specified,         * we won't test the root again, it's ignored.         * Waste no CPU retrieving the working path.         */        if (addtype == APR_EABSOLUTE && !(flags & APR_FILEPATH_NOTABOVEROOT)) {            basepath = baseroot = "";            basetype = APR_ERELATIVE;        }        /* If APR_FILEPATH_NOTABSOLUTE is specified, the caller          * requires an absolutely relative result, So do not retrieve          * the working path.         */        if (addtype == APR_ERELATIVE && (flags & APR_FILEPATH_NOTABSOLUTE)) {            basepath = baseroot = "";            basetype = APR_ERELATIVE;        }    }    if (!basepath)     {        /* Start with the current working path.  This is bass akwards,         * but required since the compiler (at least vc) doesn't like         * passing the address of a char const* for a char** arg.         * We must grab the current path of the designated drive          * if addroot is given in drive-relative form (e.g. d:foo)         */        char *getpath;#ifndef NETWARE        if (addtype == APR_EINCOMPLETE && addroot[1] == ':')            rv = filepath_drive_get(&getpath, addroot[0], flags, p);        else#endif            rv = apr_filepath_get(&getpath, flags, p);        if (rv != APR_SUCCESS)            return rv;        basepath = getpath;    }    if (!baseroot) {        /* This call should _not_ test the path         */        basetype = apr_filepath_root(&baseroot, &basepath,                                     (flags & APR_FILEPATH_NATIVE), p);        if (basetype == APR_SUCCESS) {            basetype = APR_EABSOLUTE;        }        else if (basetype == APR_ERELATIVE) {            baseroot = "";        }        else if (basetype != APR_EINCOMPLETE) {            /* apr_filepath_root was incomprehensible so fail already             */            return basetype;        }    }    baselen = strlen(basepath);    /* If APR_FILEPATH_NOTABSOLUTE is specified, the caller      * requires an absolutely relative result.  If the given      * basepath is not relative then fail.     */    if ((flags & APR_FILEPATH_NOTABSOLUTE) && basetype != APR_ERELATIVE)        return basetype;    /* The Win32 nightmare on unc street... start combining for     * many possible root combinations.     */    if (addtype == APR_EABSOLUTE)    {        /* Ignore the given root path, and start with the addroot         */        if ((flags & APR_FILEPATH_NOTABOVEROOT)                 && strncmp(baseroot, addroot, strlen(baseroot)))            return APR_EABOVEROOT;        keptlen = 0;        rootlen = pathlen = strlen(addroot);        memcpy(path, addroot, pathlen);    }    else if (addtype == APR_EINCOMPLETE)    {        /* There are several types of incomplete paths,          *     incomplete UNC paths         (//foo/ or //),         *     drives without rooted paths  (d: as in d:foo),          * and simple roots                 (/ as in /foo).         * Deal with these in significantly different manners...         */#ifndef NETWARE        if ((addroot[0] == '/' || addroot[0] == '\\') &&            (addroot[1] == '/' || addroot[1] == '\\'))         {            /* Ignore the given root path if the incomplete addpath is UNC,             * (note that the final result will be incomplete).             */            if (flags & APR_FILEPATH_NOTRELATIVE)                return addtype;            if ((flags & APR_FILEPATH_NOTABOVEROOT)                     && strncmp(baseroot, addroot, strlen(baseroot)))                return APR_EABOVEROOT;            fixunc = 1;            keptlen = 0;            rootlen = pathlen = strlen(addroot);            memcpy(path, addroot, pathlen);        }        else#endif                    if ((addroot[0] == '/' || addroot[0] == '\\') && !addroot[1])         {            /* Bring together the drive or UNC root from the baseroot             * if the addpath is a simple root and basepath is rooted,             * otherwise disregard the basepath entirely.             */            if (basetype != APR_EABSOLUTE && (flags & APR_FILEPATH_NOTRELATIVE))                return basetype;            if (basetype != APR_ERELATIVE) {#ifndef NETWARE                if (basetype == APR_INCOMPLETE                         && (baseroot[0] == '/' || baseroot[0] == '\\')                        && (baseroot[1] == '/' || baseroot[1] == '\\'))                    fixunc = 1;#endif                keptlen = rootlen = pathlen = strlen(baseroot);                memcpy(path, baseroot, pathlen);            }            else {                if (flags & APR_FILEPATH_NOTABOVEROOT)                    return APR_EABOVEROOT;                keptlen = 0;                rootlen = pathlen = strlen(addroot);                memcpy(path, addroot, pathlen);            }        }#ifdef NETWARE        else if (filepath_has_drive(addroot, DRIVE_ONLY, p))         {            /* If the addroot is a drive (without a volume root)             * use the basepath _if_ it matches this drive letter!             * Otherwise we must discard the basepath.             */            if (!filepath_compare_drive(addroot, baseroot, p) &&                 filepath_has_drive(baseroot, 0, p)) {#else        else if (addroot[0] && addroot[1] == ':' && !addroot[2])         {            /* If the addroot is a drive (without a volume root)             * use the basepath _if_ it matches this drive letter!             * Otherwise we must discard the basepath.             */            if (addroot[0] == baseroot[0] && baseroot[1] == ':') {#endif                /* Base the result path on the basepath                 */                if (basetype != APR_EABSOLUTE && (flags & APR_FILEPATH_NOTRELATIVE))                    return basetype;                rootlen = strlen(baseroot);                keptlen = pathlen = rootlen + baselen;                if (keptlen >= sizeof(path))                    return APR_ENAMETOOLONG;                memcpy(path, baseroot, rootlen);                memcpy(path + rootlen, basepath, baselen);            }             else {                if (flags & APR_FILEPATH_NOTRELATIVE)                    return addtype;                if (flags & APR_FILEPATH_NOTABOVEROOT)                    return APR_EABOVEROOT;                keptlen = 0;                rootlen = pathlen = strlen(addroot);                memcpy(path, addroot, pathlen);            }        }        else {            /* Now this is unexpected, we aren't aware of any other             * incomplete path forms!  Fail now.             */            return APR_EBADPATH;        }    }    else { /* addtype == APR_ERELATIVE */        /* If both paths are relative, fail early         */        if (basetype != APR_EABSOLUTE && (flags & APR_FILEPATH_NOTRELATIVE))            return basetype;#ifndef NETWARE        /* An incomplete UNC path must be completed         */        if (basetype == APR_INCOMPLETE                 && (baseroot[0] == '/' || baseroot[0] == '\\')                && (baseroot[1] == '/' || baseroot[1] == '\\'))            fixunc = 1;#endif        /* Base the result path on the basepath         */        rootlen = strlen(baseroot);        keptlen = pathlen = rootlen + baselen;        if (keptlen >= sizeof(path))            return APR_ENAMETOOLONG;        memcpy(path, baseroot, rootlen);        memcpy(path + rootlen, basepath, baselen);    }    /* '/' terminate the given root path unless it's already terminated     * or is an incomplete drive root.  Correct the trailing slash unless     * we have an incomplete UNC path still to fix.     */    if (pathlen && path[pathlen - 1] != ':') {        if (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\') {            if (pathlen + 1 >= sizeof(path))                return APR_ENAMETOOLONG;                    path[pathlen++] = ((flags & APR_FILEPATH_NATIVE) ? '\\' : '/');        }    /*  XXX: wrong, but gotta figure out what I intended;     *  else if (!fixunc)     *      path[pathlen++] = ((flags & APR_FILEPATH_NATIVE) ? '\\' : '/');     */    }    while (*addpath)     {        /* Parse each segment, find the closing '/'          */        seglen = 0;        while (addpath[seglen] && addpath[seglen] != '/'                               && addpath[seglen] != '\\')            ++seglen;        /* Truncate all trailing spaces and all but the first two dots */        segend = seglen;        while (seglen && (addpath[seglen - 1] == ' '                        || addpath[seglen - 1] == '.')) {            if (seglen > 2 || addpath[seglen - 1] != '.' || addpath[0] != '.')                --seglen;            else                break;        }        if (seglen == 0 || (seglen == 1 && addpath[0] == '.'))         {            /* NOTE: win32 _hates_ '/ /' and '/. /' (yes, with spaces in there)             * so eliminate all preconceptions that it is valid.             */            if (seglen < segend)                return APR_EBADPATH;#ifndef NETWARE            /* This isn't legal unless the unc path is completed             */            if (fixunc)                return APR_EBADPATH;#endif            /* Otherwise, this is a noop segment (/ or ./) so ignore it              */        }        else if (seglen == 2 && addpath[0] == '.' && addpath[1] == '.') 

⌨️ 快捷键说明

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