📄 repos.c
字号:
fsctx.uri_buf.buf[fsctx.uri_buf.cur_len] = '\0'; } /* the current resource's URI is stored in the uri_buf buffer */ fsctx.res1.uri = fsctx.uri_buf.buf; /* point the callback's resource at our structure */ fsctx.wres.resource = &fsctx.res1; /* always return the error, and any/all multistatus responses */ err = dav_fs_walker(&fsctx, depth); *response = fsctx.wres.response; return err;}static dav_error * dav_fs_walk(const dav_walk_params *params, int depth, dav_response **response){ /* always return the error, and any/all multistatus responses */ return dav_fs_internal_walk(params, depth, 0, NULL, response);}/* dav_fs_etag: Stolen from ap_make_etag. Creates a strong etag * for file path. * ### do we need to return weak tags sometimes? */static const char *dav_fs_getetag(const dav_resource *resource){ dav_resource_private *ctx = resource->info; if (!resource->exists) return apr_pstrdup(ctx->pool, ""); if (ctx->finfo.filetype != 0) { return apr_psprintf(ctx->pool, "\"%lx-%lx-%lx\"", (unsigned long) ctx->finfo.inode, (unsigned long) ctx->finfo.size, (unsigned long) ctx->finfo.mtime); } return apr_psprintf(ctx->pool, "\"%lx\"", (unsigned long) ctx->finfo.mtime);}static const dav_hooks_repository dav_hooks_repository_fs ={ DEBUG_GET_HANDLER, /* normally: special GET handling not required */ dav_fs_get_resource, dav_fs_get_parent_resource, dav_fs_is_same_resource, dav_fs_is_parent_resource, dav_fs_open_stream, dav_fs_close_stream, dav_fs_read_stream, dav_fs_write_stream, dav_fs_seek_stream, dav_fs_set_headers,#if DEBUG_PATHNAME_STYLE dav_fs_get_pathname,#else 0,#endif dav_fs_free_file, dav_fs_create_collection, dav_fs_copy_resource, dav_fs_move_resource, dav_fs_remove_resource, dav_fs_walk, dav_fs_getetag,};static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, int propid, dav_prop_insert what, ap_text_header *phdr){ const char *value; const char *s; apr_pool_t *p = resource->info->pool; const dav_liveprop_spec *info; int global_ns; /* an HTTP-date can be 29 chars plus a null term */ /* a 64-bit size can be 20 chars plus a null term */ char buf[DAV_TIMEBUF_SIZE]; /* ** None of FS provider properties are defined if the resource does not ** exist. Just bail for this case. ** ** Even though we state that the FS properties are not defined, the ** client cannot store dead values -- we deny that thru the is_writable ** hook function. */ if (!resource->exists) return DAV_PROP_INSERT_NOTDEF; switch (propid) { case DAV_PROPID_creationdate: /* ** Closest thing to a creation date. since we don't actually ** perform the operations that would modify ctime (after we ** create the file), then we should be pretty safe here. */ dav_format_time(DAV_STYLE_ISO8601, resource->info->finfo.ctime, buf); value = buf; break; case DAV_PROPID_getcontentlength: /* our property, but not defined on collection resources */ if (resource->collection) return DAV_PROP_INSERT_NOTDEF; (void) sprintf(buf, "%" APR_OFF_T_FMT, resource->info->finfo.size); value = buf; break; case DAV_PROPID_getetag: value = dav_fs_getetag(resource); break; case DAV_PROPID_getlastmodified: dav_format_time(DAV_STYLE_RFC822, resource->info->finfo.mtime, buf); value = buf; break; case DAV_PROPID_FS_executable: /* our property, but not defined on collection resources */ if (resource->collection) return DAV_PROP_INSERT_NOTDEF; /* our property, but not defined on this platform */ if (!(resource->info->finfo.valid & APR_FINFO_UPROT)) return DAV_PROP_INSERT_NOTDEF; /* the files are "ours" so we only need to check owner exec privs */ if (resource->info->finfo.protection & APR_UEXECUTE) value = "T"; else value = "F"; break; default: /* ### what the heck was this property? */ return DAV_PROP_INSERT_NOTDEF; } /* assert: value != NULL */ /* get the information and global NS index for the property */ global_ns = dav_get_liveprop_info(propid, &dav_fs_liveprop_group, &info); /* assert: info != NULL && info->name != NULL */ /* DBG3("FS: inserting lp%d:%s (local %d)", ns, scan->name, scan->ns); */ if (what == DAV_PROP_INSERT_VALUE) { s = apr_psprintf(p, "<lp%d:%s>%s</lp%d:%s>" DEBUG_CR, global_ns, info->name, value, global_ns, info->name); } else if (what == DAV_PROP_INSERT_NAME) { s = apr_psprintf(p, "<lp%d:%s/>" DEBUG_CR, global_ns, info->name); } else { /* assert: what == DAV_PROP_INSERT_SUPPORTED */ s = apr_psprintf(p, "<D:supported-live-property D:name=\"%s\" " "D:namespace=\"%s\"/>" DEBUG_CR, info->name, dav_fs_namespace_uris[info->ns]); } ap_text_append(p, phdr, s); /* we inserted what was asked for */ return what;}static int dav_fs_is_writable(const dav_resource *resource, int propid){ const dav_liveprop_spec *info;#ifndef WIN32 /* this property is not usable (writable) on the Win32 platform */ if (propid == DAV_PROPID_FS_executable && !resource->collection) return 1;#endif (void) dav_get_liveprop_info(propid, &dav_fs_liveprop_group, &info); return info->is_writable;}static dav_error *dav_fs_patch_validate(const dav_resource *resource, const ap_xml_elem *elem, int operation, void **context, int *defer_to_dead){ const ap_text *cdata; const ap_text *f_cdata; char value; dav_elem_private *priv = elem->private; if (priv->propid != DAV_PROPID_FS_executable) { *defer_to_dead = 1; return NULL; } if (operation == DAV_PROP_OP_DELETE) { return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, "The 'executable' property cannot be removed."); } cdata = elem->first_cdata.first; /* ### hmm. this isn't actually looking at all the possible text items */ f_cdata = elem->first_child == NULL ? NULL : elem->first_child->following_cdata.first; /* DBG3("name=%s cdata=%s f_cdata=%s",elem->name,cdata ? cdata->text : "[null]",f_cdata ? f_cdata->text : "[null]"); */ if (cdata == NULL) { if (f_cdata == NULL) { return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, "The 'executable' property expects a single " "character, valued 'T' or 'F'. There was no " "value submitted."); } cdata = f_cdata; } else if (f_cdata != NULL) goto too_long; if (cdata->next != NULL || strlen(cdata->text) != 1) goto too_long; value = cdata->text[0]; if (value != 'T' && value != 'F') { return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, "The 'executable' property expects a single " "character, valued 'T' or 'F'. The value " "submitted is invalid."); } *context = (void *)(value == 'T'); return NULL; too_long: return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, "The 'executable' property expects a single " "character, valued 'T' or 'F'. The value submitted " "has too many characters.");}static dav_error *dav_fs_patch_exec(const dav_resource *resource, const ap_xml_elem *elem, int operation, void *context, dav_liveprop_rollback **rollback_ctx){ int value = context != NULL; apr_fileperms_t perms = resource->info->finfo.protection; int old_value = (perms & APR_UEXECUTE) != 0; /* assert: prop == executable. operation == SET. */ /* don't do anything if there is no change. no rollback info either. */ /* DBG2("new value=%d (old=%d)", value, old_value); */ if (value == old_value) return NULL; perms &= ~APR_UEXECUTE; if (value) perms |= APR_UEXECUTE; if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) { return dav_new_error(resource->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0, "Could not set the executable flag of the " "target resource."); } /* update the resource and set up the rollback context */ resource->info->finfo.protection = perms; *rollback_ctx = (dav_liveprop_rollback *)old_value; return NULL;}static void dav_fs_patch_commit(const dav_resource *resource, int operation, void *context, dav_liveprop_rollback *rollback_ctx){ /* nothing to do */}static dav_error *dav_fs_patch_rollback(const dav_resource *resource, int operation, void *context, dav_liveprop_rollback *rollback_ctx){ apr_fileperms_t perms = resource->info->finfo.protection & ~APR_UEXECUTE; int value = rollback_ctx != NULL; /* assert: prop == executable. operation == SET. */ /* restore the executable bit */ if (value) perms |= APR_UEXECUTE; if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) { return dav_new_error(resource->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0, "After a failure occurred, the resource's " "executable flag could not be restored."); } /* restore the resource's state */ resource->info->finfo.protection = perms; return NULL;}static const dav_hooks_liveprop dav_hooks_liveprop_fs ={ dav_fs_insert_prop, dav_fs_is_writable, dav_fs_namespace_uris, dav_fs_patch_validate, dav_fs_patch_exec, dav_fs_patch_commit, dav_fs_patch_rollback};static const dav_provider dav_fs_provider ={ &dav_hooks_repository_fs, &dav_hooks_db_dbm, &dav_hooks_locks_fs, NULL, /* vsn */ NULL /* binding */};void dav_fs_gather_propsets(apr_array_header_t *uris){#ifndef WIN32 *(const char **)apr_array_push(uris) = "<http://apache.org/dav/propset/fs/1>";#endif}int dav_fs_find_liveprop(const dav_resource *resource, const char *ns_uri, const char *name, const dav_hooks_liveprop **hooks){ /* don't try to find any liveprops if this isn't "our" resource */ if (resource->hooks != &dav_hooks_repository_fs) return 0; return dav_do_find_liveprop(ns_uri, name, &dav_fs_liveprop_group, hooks);}void dav_fs_insert_all_liveprops(request_rec *r, const dav_resource *resource, dav_prop_insert what, ap_text_header *phdr){ /* don't insert any liveprops if this isn't "our" resource */ if (resource->hooks != &dav_hooks_repository_fs) return; if (!resource->exists) { /* a lock-null resource */ /* ** ### technically, we should insert empty properties. dunno offhand ** ### what part of the spec said this, but it was essentially thus: ** ### "the properties should be defined, but may have no value". */ return; } (void) dav_fs_insert_prop(resource, DAV_PROPID_creationdate, what, phdr); (void) dav_fs_insert_prop(resource, DAV_PROPID_getcontentlength, what, phdr); (void) dav_fs_insert_prop(resource, DAV_PROPID_getlastmodified, what, phdr); (void) dav_fs_insert_prop(resource, DAV_PROPID_getetag, what, phdr);#ifndef WIN32 /* ** Note: this property is not defined on the Win32 platform. ** dav_fs_insert_prop() won't insert it, but we may as ** well not even call it. */ (void) dav_fs_insert_prop(resource, DAV_PROPID_FS_executable, what, phdr);#endif /* ### we know the others aren't defined as liveprops */}void dav_fs_register(apr_pool_t *p){ /* register the namespace URIs */ dav_register_liveprop_group(p, &dav_fs_liveprop_group); /* register the repository provider */ dav_register_provider(p, "filesystem", &dav_fs_provider);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -