diff options
author | sborrill <sborrill@pkgsrc.org> | 2011-09-12 17:18:46 +0000 |
---|---|---|
committer | sborrill <sborrill@pkgsrc.org> | 2011-09-12 17:18:46 +0000 |
commit | f8b8c2e4112abe00edea46cfe84b80d94e37ae4d (patch) | |
tree | b594c3d57447a17c8342dac4774a68ba7a2084bd /www/apache22 | |
parent | d7656fb839496e942a620dd82b7af44506057569 (diff) | |
download | pkgsrc-f8b8c2e4112abe00edea46cfe84b80d94e37ae4d.tar.gz |
Atomically create files when using DAV to stop files being deleted on error
From:
https://issues.apache.org/bugzilla/show_bug.cgi?id=39815
Bump PKGREVISION.
OK tron@
Diffstat (limited to 'www/apache22')
-rw-r--r-- | www/apache22/Makefile | 4 | ||||
-rw-r--r-- | www/apache22/distinfo | 4 | ||||
-rw-r--r-- | www/apache22/patches/patch-lock.c | 58 | ||||
-rw-r--r-- | www/apache22/patches/patch-repos.c | 99 |
4 files changed, 163 insertions, 2 deletions
diff --git a/www/apache22/Makefile b/www/apache22/Makefile index 3081736a3c3..6423916feb7 100644 --- a/www/apache22/Makefile +++ b/www/apache22/Makefile @@ -1,6 +1,8 @@ -# $NetBSD: Makefile,v 1.68 2011/08/31 12:52:45 tron Exp $ +# $NetBSD: Makefile,v 1.69 2011/09/12 17:18:46 sborrill Exp $ DISTNAME= httpd-2.2.20 +PKGREVISION= 1 + PKGNAME= ${DISTNAME:S/httpd/apache/} CATEGORIES= www MASTER_SITES= ${MASTER_SITE_APACHE:=httpd/} \ diff --git a/www/apache22/distinfo b/www/apache22/distinfo index d372b967713..97dac664dc9 100644 --- a/www/apache22/distinfo +++ b/www/apache22/distinfo @@ -1,4 +1,4 @@ -$NetBSD: distinfo,v 1.40 2011/08/31 12:52:45 tron Exp $ +$NetBSD: distinfo,v 1.41 2011/09/12 17:18:46 sborrill Exp $ SHA1 (httpd-2.2.20.tar.bz2) = c8f00a505af6ed3f89f45b640217c388f5cd32b0 RMD160 (httpd-2.2.20.tar.bz2) = 299d1a8a9f3a6eb925d63ce96fa8ea4a06ec1f17 @@ -14,3 +14,5 @@ SHA1 (patch-ai) = 4ebc3bd580a298973928eb6d13d2ce745eac0312 SHA1 (patch-al) = 56b9f5c2f6fd01fe5067f9210e328cbf674c68f1 SHA1 (patch-am) = ab4a2f7e5a1a3064e908b61157e7fd349c0b0c08 SHA1 (patch-aw) = ca53d67beeb2c2c4d9adb04d3d79e24a8c427fd4 +SHA1 (patch-lock.c) = 770ca03f1cb4421879bd5baa5a7c30cc91acb6e1 +SHA1 (patch-repos.c) = 0e0361b91d4b0fe6c7c55a12fdfd2e6aacc710e1 diff --git a/www/apache22/patches/patch-lock.c b/www/apache22/patches/patch-lock.c new file mode 100644 index 00000000000..16e920fd749 --- /dev/null +++ b/www/apache22/patches/patch-lock.c @@ -0,0 +1,58 @@ +$NetBSD: patch-lock.c,v 1.1 2011/09/12 17:18:46 sborrill Exp $ + +Atomically create files when using DAV to stop files being deleted on error + +From: +https://issues.apache.org/bugzilla/show_bug.cgi?id=39815 + +--- modules/dav/fs/lock.c.orig 2007-11-29 21:21:10.000000000 +0100 ++++ modules/dav/fs/lock.c 2009-07-10 13:42:43.000000000 +0200 +@@ -398,46 +398,48 @@ + ** to look up lock information for this file. + ** + ** (inode/dev not supported or file is lock-null): + ** apr_datum_t->dvalue = full path + ** + ** (inode/dev supported and file exists ): + ** apr_datum_t->dvalue = inode, dev + */ + static apr_datum_t dav_fs_build_key(apr_pool_t *p, + const dav_resource *resource) + { + const char *file = dav_fs_pathname(resource); ++#if 0 + apr_datum_t key; + apr_finfo_t finfo; + apr_status_t rv; + + /* ### use lstat() ?? */ + /* + * XXX: What for platforms with no IDENT (dev/inode)? + */ + rv = apr_stat(&finfo, file, APR_FINFO_IDENT, p); + if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE) + && ((finfo.valid & APR_FINFO_IDENT) == APR_FINFO_IDENT)) + { + /* ### can we use a buffer for this? */ + key.dsize = 1 + sizeof(finfo.inode) + sizeof(finfo.device); + key.dptr = apr_palloc(p, key.dsize); + *key.dptr = DAV_TYPE_INODE; + memcpy(key.dptr + 1, &finfo.inode, sizeof(finfo.inode)); + memcpy(key.dptr + 1 + sizeof(finfo.inode), &finfo.device, + sizeof(finfo.device)); + + return key; + } ++#endif + + return dav_fs_build_fname_key(p, file); + } + + /* + ** dav_fs_lock_expired: return 1 (true) if the given timeout is in the past + ** or present (the lock has expired), or 0 (false) if in the future + ** (the lock has not yet expired). + */ + static int dav_fs_lock_expired(time_t expires) + { + return expires != DAV_TIMEOUT_INFINITE && time(NULL) >= expires; diff --git a/www/apache22/patches/patch-repos.c b/www/apache22/patches/patch-repos.c new file mode 100644 index 00000000000..2242b39e48a --- /dev/null +++ b/www/apache22/patches/patch-repos.c @@ -0,0 +1,99 @@ +$NetBSD: patch-repos.c,v 1.1 2011/09/12 17:18:46 sborrill Exp $ + +Atomically create files when using DAV to stop files being deleted on error + +From: +https://issues.apache.org/bugzilla/show_bug.cgi?id=39815 + +--- modules/dav/fs/repos.c.orig 2008-08-16 00:12:47.000000000 +0200 ++++ modules/dav/fs/repos.c 2009-07-10 19:01:24.000000000 +0200 +@@ -191,6 +191,7 @@ + apr_pool_t *p; + apr_file_t *f; + const char *pathname; /* we may need to remove it at close time */ ++ const char *temppath; + }; + + /* returns an appropriate HTTP status code given an APR status code for a +@@ -841,6 +842,14 @@ + && ctx2->pathname[len1] == '/'); + } + ++static apr_status_t tmpfile_cleanup(void *data) { ++ dav_stream *ds = data; ++ if (ds->temppath) { ++ apr_file_remove(ds->temppath, ds->p); ++ } ++ return APR_SUCCESS; ++} ++ + static dav_error * dav_fs_open_stream(const dav_resource *resource, + dav_stream_mode mode, + dav_stream **stream) +@@ -849,6 +858,7 @@ + dav_stream *ds = apr_pcalloc(p, sizeof(*ds)); + apr_int32_t flags; + apr_status_t rv; ++ char* fpath; + + switch (mode) { + default: +@@ -865,7 +875,18 @@ + + ds->p = p; + ds->pathname = resource->info->pathname; +- rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p); ++ ds->temppath = NULL; ++ ++ if (mode == DAV_MODE_WRITE_TRUNC) { ++ fpath = apr_pstrcat(p, ds->pathname, ".tmp.XXXXXX", NULL); ++ rv = apr_file_mktemp(&ds->f, fpath, flags, ds->p); ++ ds->temppath = fpath; ++ apr_pool_cleanup_register(p, ds, tmpfile_cleanup, apr_pool_cleanup_null); ++ } ++ else { ++ 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."); +@@ -879,16 +900,32 @@ + + static dav_error * dav_fs_close_stream(dav_stream *stream, int commit) + { ++ apr_status_t rv; ++ + 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."); ++ if (stream->temppath) { ++ apr_pool_cleanup_run(stream->p, stream, tmpfile_cleanup); ++ } ++ else { ++ 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."); ++ } ++ } ++ } ++ else if (stream->temppath) { ++ rv = apr_file_rename(stream->temppath, stream->pathname, stream->p); ++ if (rv) { ++ return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, rv, ++ "There was a problem writing the file " ++ "atomically after writes."); + } ++ apr_pool_cleanup_kill(stream->p, stream, tmpfile_cleanup); + } + + return NULL; |