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

📄 repos.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 5 页
字号:
        /*        ** ### strictly speaking, this is a design error; we should not        ** ### have reached this point.        */        return dav_new_error(src->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0,                             "DESIGN ERROR: a mix of repositories "                             "was passed to copy_resource.");    }#endif    if ((err = dav_fs_copymove_resource(0, src, dst, depth,                                        response)) == NULL) {        /* update state of destination resource to show it exists */        dst->exists = 1;        dst->collection = src->collection;    }    return err;}static dav_error * dav_fs_move_resource(    dav_resource *src,    dav_resource *dst,    dav_response **response){    dav_resource_private *srcinfo = src->info;    dav_resource_private *dstinfo = dst->info;    dav_error *err;    int can_rename = 0;#if DAV_DEBUG    if (src->hooks != dst->hooks) {        /*        ** ### strictly speaking, this is a design error; we should not        ** ### have reached this point.        */        return dav_new_error(src->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0,                             "DESIGN ERROR: a mix of repositories "                             "was passed to move_resource.");    }#endif    /* determine whether a simple rename will work.     * Assume source exists, else we wouldn't get called.     */    if (dstinfo->finfo.filetype != 0) {        if (dstinfo->finfo.device == srcinfo->finfo.device) {            /* target exists and is on the same device. */            can_rename = 1;        }    }    else {        const char *dirpath;        apr_finfo_t finfo;        apr_status_t rv;        /* destination does not exist, but the parent directory should,         * so try it         */        dirpath = ap_make_dirstr_parent(dstinfo->pool, dstinfo->pathname);        /*         * XXX: If missing dev ... then what test?         * Really need a try and failover for those platforms.         *         */        rv = apr_stat(&finfo, dirpath, APR_FINFO_DEV, dstinfo->pool);        if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE)            && (finfo.valid & srcinfo->finfo.valid & APR_FINFO_DEV)            && (finfo.device == srcinfo->finfo.device)) {            can_rename = 1;        }    }    /* if we can't simply rename, then do it the hard way... */    if (!can_rename) {        if ((err = dav_fs_copymove_resource(1, src, dst, DAV_INFINITY,                                            response)) == NULL) {            /* update resource states */            dst->exists = 1;            dst->collection = src->collection;            src->exists = 0;            src->collection = 0;        }        return err;    }    /* a rename should work. do it, and move properties as well */    /* no multistatus response */    *response = NULL;    /* ### APR has no rename? */    if (apr_file_rename(srcinfo->pathname, dstinfo->pathname,                       srcinfo->pool) != APR_SUCCESS) {        /* ### should have a better error than this. */        return dav_new_error(srcinfo->pool, HTTP_INTERNAL_SERVER_ERROR, 0,                             "Could not rename resource.");    }    /* update resource states */    dst->exists = 1;    dst->collection = src->collection;    src->exists = 0;    src->collection = 0;    if ((err = dav_fs_copymoveset(1, src->info->pool,                                  src, dst, NULL)) == NULL) {        /* no error. we're done. go ahead and return now. */        return NULL;    }    /* error occurred during properties move; try to put resource back */    if (apr_file_rename(dstinfo->pathname, srcinfo->pathname,                       srcinfo->pool) != APR_SUCCESS) {        /* couldn't put it back! */        return dav_push_error(srcinfo->pool,                              HTTP_INTERNAL_SERVER_ERROR, 0,                              "The resource was moved, but a failure "                              "occurred during the move of its "                              "properties. The resource could not be "                              "restored to its original location. The "                              "server is now in an inconsistent state.",                              err);    }    /* update resource states again */    src->exists = 1;    src->collection = dst->collection;    dst->exists = 0;    dst->collection = 0;    /* resource moved back, but properties may be inconsistent */    return dav_push_error(srcinfo->pool,                          HTTP_INTERNAL_SERVER_ERROR, 0,                          "The resource was moved, but a failure "                          "occurred during the move of its properties. "                          "The resource was moved back to its original "                          "location, but its properties may have been "                          "partially moved. The server may be in an "                          "inconsistent state.",                          err);}static dav_error * dav_fs_delete_walker(dav_walk_resource *wres, int calltype){    dav_resource_private *info = wres->resource->info;    /* do not attempt to remove a null resource,     * or a collection with children     */    if (wres->resource->exists &&        (!wres->resource->collection || calltype == DAV_CALLTYPE_POSTFIX)) {        /* try to remove the resource */        apr_status_t result;        result = wres->resource->collection            ? apr_dir_remove(info->pathname, wres->pool)            : apr_file_remove(info->pathname, wres->pool);        /*        ** If an error occurred, then add it to multistatus response.        ** Note that we add it for the root resource, too. It is quite        ** possible to delete the whole darn tree, yet fail on the root.        **        ** (also: remember we are deleting via a postfix traversal)        */        if (result != APR_SUCCESS) {            /* ### assume there is a permissions problem */            /* ### use errno to generate DAV:responsedescription? */            dav_add_response(wres, HTTP_FORBIDDEN, NULL);        }    }    return NULL;}static dav_error * dav_fs_remove_resource(dav_resource *resource,                                          dav_response **response){    dav_resource_private *info = resource->info;    *response = NULL;    /* if a collection, recursively remove it and its children,     * including the state dirs     */    if (resource->collection) {        dav_walk_params params = { 0 };        dav_error *err = NULL;        dav_response *multi_status;        params.walk_type = (DAV_WALKTYPE_NORMAL                            | DAV_WALKTYPE_HIDDEN                            | DAV_WALKTYPE_POSTFIX);        params.func = dav_fs_delete_walker;        params.pool = info->pool;        params.root = resource;        if ((err = dav_fs_walk(&params, DAV_INFINITY,                               &multi_status)) != NULL) {            /* on a "real" error, then just punt. nothing else to do. */            return err;        }        if ((*response = multi_status) != NULL) {            /* some multistatus responses exist. wrap them in a 207 */            return dav_new_error(info->pool, HTTP_MULTI_STATUS, 0,                                 "Error(s) occurred on some resources during "                                 "the deletion process.");        }        /* no errors... update resource state */        resource->exists = 0;        resource->collection = 0;        return NULL;    }    /* not a collection; remove the file and its properties */    if (apr_file_remove(info->pathname, info->pool) != APR_SUCCESS) {        /* ### put a description in here */        return dav_new_error(info->pool, HTTP_FORBIDDEN, 0, NULL);    }    /* update resource state */    resource->exists = 0;    resource->collection = 0;    /* remove properties and return its result */    return dav_fs_deleteset(info->pool, resource);}/* ### move this to dav_util? *//* Walk recursively down through directories, * * including lock-null resources as we go.    */static dav_error * dav_fs_walker(dav_fs_walker_context *fsctx, int depth){    const dav_walk_params *params = fsctx->params;    apr_pool_t *pool = params->pool;    dav_error *err = NULL;    int isdir = fsctx->res1.collection;    apr_finfo_t dirent;    apr_dir_t *dirp;    /* ensure the context is prepared properly, then call the func */    err = (*params->func)(&fsctx->wres,                          isdir                          ? DAV_CALLTYPE_COLLECTION                          : DAV_CALLTYPE_MEMBER);    if (err != NULL) {        return err;    }    if (depth == 0 || !isdir) {        return NULL;    }    /* put a trailing slash onto the directory, in preparation for appending     * files to it as we discovery them within the directory */    dav_check_bufsize(pool, &fsctx->path1, DAV_BUFFER_PAD);    fsctx->path1.buf[fsctx->path1.cur_len++] = '/';    fsctx->path1.buf[fsctx->path1.cur_len] = '\0';        /* in pad area */    /* if a secondary path is present, then do that, too */    if (fsctx->path2.buf != NULL) {        dav_check_bufsize(pool, &fsctx->path2, DAV_BUFFER_PAD);        fsctx->path2.buf[fsctx->path2.cur_len++] = '/';        fsctx->path2.buf[fsctx->path2.cur_len] = '\0';        /* in pad area */    }    /* Note: the URI should ALREADY have a trailing "/" */    /* for this first pass of files, all resources exist */    fsctx->res1.exists = 1;    /* a file is the default; we'll adjust if we hit a directory */    fsctx->res1.collection = 0;    fsctx->res2.collection = 0;    /* open and scan the directory */    if ((apr_dir_open(&dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) {        /* ### need a better error */        return dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);    }    while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) {        apr_size_t len;        apr_status_t status;        len = strlen(dirent.name);        /* avoid recursing into our current, parent, or state directories */        if (dirent.name[0] == '.'              && (len == 1 || (dirent.name[1] == '.' && len == 2))) {            continue;        }        if (params->walk_type & DAV_WALKTYPE_AUTH) {            /* ### need to authorize each file */            /* ### example: .htaccess is normally configured to fail auth */            /* stuff in the state directory is never authorized! */            if (!strcmp(dirent.name, DAV_FS_STATE_DIR)) {                continue;            }        }        /* skip the state dir unless a HIDDEN is performed */        if (!(params->walk_type & DAV_WALKTYPE_HIDDEN)            && !strcmp(dirent.name, DAV_FS_STATE_DIR)) {            continue;        }        /* append this file onto the path buffer (copy null term) */        dav_buffer_place_mem(pool, &fsctx->path1, dirent.name, len + 1, 0);        /* ### Optimize me, dirent can give us what we need! */        status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf,                          APR_FINFO_NORM | APR_FINFO_LINK, pool);        if (status != APR_SUCCESS && status != APR_INCOMPLETE) {            /* woah! where'd it go? */            /* ### should have a better error here */            err = dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);            break;        }        /* copy the file to the URI, too. NOTE: we will pad an extra byte           for the trailing slash later. */        dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1);        /* if there is a secondary path, then do that, too */        if (fsctx->path2.buf != NULL) {            dav_buffer_place_mem(pool, &fsctx->path2, dirent.name, len + 1, 0);        }        /* set up the (internal) pathnames for the two resources */        fsctx->info1.pathname = fsctx->path1.buf;        fsctx->info2.pathname = fsctx->path2.buf;        /* set up the URI for the current resource */        fsctx->res1.uri = fsctx->uri_buf.buf;        /* ### for now, only process regular files (e.g. skip symlinks) */        if (fsctx->info1.finfo.filetype == APR_REG) {            /* call the function for the specified dir + file */            if ((err = (*params->func)(&fsctx->wres,                                       DAV_CALLTYPE_MEMBER)) != NULL) {                /* ### maybe add a higher-level description? */                break;            }        }        else if (fsctx->info1.finfo.filetype == APR_DIR) {            apr_size_t save_path_len = fsctx->path1.cur_len;            apr_size_t save_uri_len = fsctx->uri_buf.cur_len;            apr_size_t save_path2_len = fsctx->path2.cur_len;            /* adjust length to incorporate the subdir name */            fsctx->path1.cur_len += len;            fsctx->path2.cur_len += len;            /* adjust URI length to incorporate subdir and a slash */            fsctx->uri_buf.cur_len += len + 1;            fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/';            fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0';            /* switch over to a collection */            fsctx->res1.collection = 1;            fsctx->res2.collection = 1;            /* recurse on the subdir */            /* ### don't always want to quit on error from single child */            if ((err = dav_fs_walker(fsctx, depth - 1)) != NULL) {                /* ### maybe add a higher-level description? */                break;            }            /* put the various information back */            fsctx->path1.cur_len = save_path_len;            fsctx->path2.cur_len = save_path2_len;            fsctx->uri_buf.cur_len = save_uri_len;            fsctx->res1.collection = 0;            fsctx->res2.collection = 0;            /* assert: res1.exists == 1 */        }

⌨️ 快捷键说明

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