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

📄 repos.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (resource->uri != NULL) {        char *uri = ap_make_dirstr_parent(ctx->pool, resource->uri);        if (strlen(uri) > 1 && uri[strlen(uri) - 1] == '/')            uri[strlen(uri) - 1] = '\0';        parent_resource->uri = uri;    }    rv = apr_stat(&parent_ctx->finfo, parent_ctx->pathname,                  APR_FINFO_NORM, ctx->pool);    if (rv == APR_SUCCESS || rv == APR_INCOMPLETE) {        parent_resource->exists = 1;    }    *result_parent = parent_resource;    return NULL;}static int dav_fs_is_same_resource(    const dav_resource *res1,    const dav_resource *res2){    dav_resource_private *ctx1 = res1->info;    dav_resource_private *ctx2 = res2->info;    if (res1->hooks != res2->hooks)        return 0;    if ((ctx1->finfo.filetype != 0) && (ctx2->finfo.filetype != 0)        && (ctx1->finfo.valid & ctx2->finfo.valid & APR_FINFO_INODE)) {        return ctx1->finfo.inode == ctx2->finfo.inode;    }    else {        return strcmp(ctx1->pathname, ctx2->pathname) == 0;    }}static int dav_fs_is_parent_resource(    const dav_resource *res1,    const dav_resource *res2){    dav_resource_private *ctx1 = res1->info;    dav_resource_private *ctx2 = res2->info;    apr_size_t len1 = strlen(ctx1->pathname);    apr_size_t len2;    if (res1->hooks != res2->hooks)        return 0;    /* it is safe to use ctx2 now */    len2 = strlen(ctx2->pathname);    return (len2 > len1            && memcmp(ctx1->pathname, ctx2->pathname, len1) == 0            && ctx2->pathname[len1] == '/');}static dav_error * dav_fs_open_stream(const dav_resource *resource,                                      dav_stream_mode mode,                                      dav_stream **stream){    apr_pool_t *p = resource->info->pool;    dav_stream *ds = apr_pcalloc(p, sizeof(*ds));    apr_int32_t flags;    apr_status_t rv;    switch (mode) {    default:        flags = APR_READ | APR_BINARY;        break;    case DAV_MODE_WRITE_TRUNC:        flags = APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY;        break;    case DAV_MODE_WRITE_SEEKABLE:        flags = APR_WRITE | APR_CREATE | APR_BINARY;        break;    }    ds->p = p;    ds->pathname = resource->info->pathname;    rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);    if (rv != APR_SUCCESS) {        return dav_new_error(p, MAP_IO2HTTP(rv), 0,                             "An error occurred while opening a resource.");    }    /* (APR registers cleanups for the fd with the pool) */    *stream = ds;    return NULL;}static dav_error * dav_fs_close_stream(dav_stream *stream, int commit){    apr_file_close(stream->f);    if (!commit) {        if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) {            /* ### use a better description? */            return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,                                 "There was a problem removing (rolling "                                 "back) the resource "                                 "when it was being closed.");        }    }    return NULL;}static dav_error * dav_fs_write_stream(dav_stream *stream,                                       const void *buf, apr_size_t bufsize){    apr_status_t status;    status = apr_file_write_full(stream->f, buf, bufsize, NULL);    if (APR_STATUS_IS_ENOSPC(status)) {        return dav_new_error(stream->p, HTTP_INSUFFICIENT_STORAGE, 0,                             "There is not enough storage to write to "                             "this resource.");    }    else if (status != APR_SUCCESS) {        /* ### use something besides 500? */        return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,                             "An error occurred while writing to a "                             "resource.");    }    return NULL;}static dav_error * dav_fs_seek_stream(dav_stream *stream, apr_off_t abs_pos){    if (apr_file_seek(stream->f, APR_SET, &abs_pos) != APR_SUCCESS) {        /* ### should check whether apr_file_seek set abs_pos was set to the         * correct position? */        /* ### use something besides 500? */        return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,                             "Could not seek to specified position in the "                             "resource.");    }    return NULL;}#if DEBUG_GET_HANDLER/* only define set_headers() and deliver() for debug purposes */static dav_error * dav_fs_set_headers(request_rec *r,                                      const dav_resource *resource){    /* ### this function isn't really used since we have a get_pathname */    if (!resource->exists)        return NULL;    /* make sure the proper mtime is in the request record */    ap_update_mtime(r, resource->info->finfo.mtime);    /* ### note that these use r->filename rather than <resource> */    ap_set_last_modified(r);    ap_set_etag(r);    /* we accept byte-ranges */    apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");    /* set up the Content-Length header */    ap_set_content_length(r, resource->info->finfo.size);    /* ### how to set the content type? */    /* ### until this is resolved, the Content-Type header is busted */    return NULL;}static dav_error * dav_fs_deliver(const dav_resource *resource,                                  ap_filter_t *output){    apr_pool_t *pool = resource->pool;    apr_bucket_brigade *bb;    apr_file_t *fd;    apr_status_t status;    apr_bucket *bkt;    /* Check resource type */    if (resource->type != DAV_RESOURCE_TYPE_REGULAR        && resource->type != DAV_RESOURCE_TYPE_VERSION        && resource->type != DAV_RESOURCE_TYPE_WORKING) {        return dav_new_error(pool, HTTP_CONFLICT, 0,                             "Cannot GET this type of resource.");    }    if (resource->collection) {        return dav_new_error(pool, HTTP_CONFLICT, 0,                             "There is no default response to GET for a "                             "collection.");    }    if ((status = apr_file_open(&fd, resource->info->pathname,                                APR_READ | APR_BINARY, 0,                                pool)) != APR_SUCCESS) {        return dav_new_error(pool, HTTP_FORBIDDEN, 0,                             "File permissions deny server access.");    }    bb = apr_brigade_create(pool, output->c->bucket_alloc);    /* ### this does not handle large files. but this is test code anyway */    bkt = apr_bucket_file_create(fd, 0,                                 (apr_size_t)resource->info->finfo.size,                                 pool, output->c->bucket_alloc);    APR_BRIGADE_INSERT_TAIL(bb, bkt);    bkt = apr_bucket_eos_create(output->c->bucket_alloc);    APR_BRIGADE_INSERT_TAIL(bb, bkt);    if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) {        return dav_new_error(pool, HTTP_FORBIDDEN, 0,                             "Could not write contents to filter.");    }    return NULL;}#endif /* DEBUG_GET_HANDLER */static dav_error * dav_fs_create_collection(dav_resource *resource){    dav_resource_private *ctx = resource->info;    apr_status_t status;    status = apr_dir_make(ctx->pathname, APR_OS_DEFAULT, ctx->pool);    if (APR_STATUS_IS_ENOSPC(status)) {        return dav_new_error(ctx->pool, HTTP_INSUFFICIENT_STORAGE, 0,                             "There is not enough storage to create "                             "this collection.");    }    else if (APR_STATUS_IS_ENOENT(status)) {        return dav_new_error(ctx->pool, HTTP_CONFLICT, 0,                             "Cannot create collection; intermediate "                             "collection does not exist.");    }    else if (status != APR_SUCCESS) {        /* ### refine this error message? */        return dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0,                             "Unable to create collection.");    }    /* update resource state to show it exists as a collection */    resource->exists = 1;    resource->collection = 1;    return NULL;}static dav_error * dav_fs_copymove_walker(dav_walk_resource *wres,                                          int calltype){    dav_fs_copymove_walk_ctx *ctx = wres->walk_ctx;    dav_resource_private *srcinfo = wres->resource->info;    dav_resource_private *dstinfo = ctx->res_dst->info;    dav_error *err = NULL;    if (wres->resource->collection) {        if (calltype == DAV_CALLTYPE_POSTFIX) {            /* Postfix call for MOVE. delete the source dir.             * Note: when copying, we do not enable the postfix-traversal.             */            /* ### we are ignoring any error here; what should we do? */            (void) apr_dir_remove(srcinfo->pathname, ctx->pool);        }        else {            /* copy/move of a collection. Create the new, target collection */            if (apr_dir_make(dstinfo->pathname, APR_OS_DEFAULT,                             ctx->pool) != APR_SUCCESS) {                /* ### assume it was a permissions problem */                /* ### need a description here */                err = dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0, NULL);            }        }    }    else {        err = dav_fs_copymove_file(ctx->is_move, ctx->pool,                                   srcinfo->pathname, dstinfo->pathname,                                   &srcinfo->finfo,                                   ctx->res_dst->exists ? &dstinfo->finfo : NULL,                                   &ctx->work_buf);        /* ### push a higher-level description? */    }    /*    ** If we have a "not so bad" error, then it might need to go into a    ** multistatus response.    **    ** For a MOVE, it will always go into the multistatus. It could be    ** that everything has been moved *except* for the root. Using a    ** multistatus (with no errors for the other resources) will signify    ** this condition.    **    ** For a COPY, we are traversing in a prefix fashion. If the root fails,    ** then we can just bail out now.    */    if (err != NULL        && !ap_is_HTTP_SERVER_ERROR(err->status)        && (ctx->is_move            || !dav_fs_is_same_resource(wres->resource, ctx->root))) {        /* ### use errno to generate DAV:responsedescription? */        dav_add_response(wres, err->status, NULL);        /* the error is in the multistatus now. do not stop the traversal. */        return NULL;    }    return err;}static dav_error *dav_fs_copymove_resource(    int is_move,    const dav_resource *src,    const dav_resource *dst,    int depth,    dav_response **response){    dav_error *err = NULL;    dav_buffer work_buf = { 0 };    *response = NULL;    /* if a collection, recursively copy/move it and its children,     * including the state dirs     */    if (src->collection) {        dav_walk_params params = { 0 };        dav_response *multi_status;        params.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_HIDDEN;        params.func = dav_fs_copymove_walker;        params.pool = src->info->pool;        params.root = src;        /* params.walk_ctx is managed by dav_fs_internal_walk() */        /* postfix is needed for MOVE to delete source dirs */        if (is_move)            params.walk_type |= DAV_WALKTYPE_POSTFIX;        /* note that we return the error OR the multistatus. never both */        if ((err = dav_fs_internal_walk(&params, depth, is_move, dst,                                        &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(src->info->pool, HTTP_MULTI_STATUS, 0,                                 "Error(s) occurred on some resources during "                                 "the COPY/MOVE process.");        }        return NULL;    }    /* not a collection */    if ((err = dav_fs_copymove_file(is_move, src->info->pool,                                    src->info->pathname, dst->info->pathname,                                    &src->info->finfo,                                    dst->exists ? &dst->info->finfo : NULL,                                    &work_buf)) != NULL) {        /* ### push a higher-level description? */        return err;    }    /* copy/move properties as well */    return dav_fs_copymoveset(is_move, src->info->pool, src, dst, &work_buf);}static dav_error * dav_fs_copy_resource(    const dav_resource *src,    dav_resource *dst,    int depth,    dav_response **response){    dav_error *err;#if DAV_DEBUG    if (src->hooks != dst->hooks) {

⌨️ 快捷键说明

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