#include <apr_md5.h>
#include <apr_pools.h>
#include <apr_user.h>
#include <apr_file_io.h>
#include <subversion-1/svn_delta.h>
#include <subversion-1/svn_ra.h>
#include <subversion-1/svn_error.h>
#include <subversion-1/svn_string.h>
#include <subversion-1/svn_time.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include <fcntl.h>
#include "global.h"
#include "helper.h"
#include "url.h"
#include "status.h"
#include "racallback.h"
#include "props.h"
#include "checksum.h"
#include "revert.h"
#include "warnings.h"
#include "est_ops.h"
#include "waa.h"
#include "commit.h"
Go to the source code of this file.
Functions | |
int | up__fetch_decoder (struct estat *sts) |
Prefetch update-pipe property. | |
int | up__parse_prop (struct estat *sts, const char *utf8_name, const svn_string_t *utf8_value, int *not_handled, apr_pool_t *pool) |
-. | |
int | up__unlink (struct estat *sts, char *filename) |
-. | |
int | up__rmdir (struct estat *sts, struct url_t *url) |
Recursively delete a directory structure. | |
int | up__set_meta_data (struct estat *sts, char *filename) |
-. | |
int | up__handle_special (struct estat *sts, char *path, char *data, apr_pool_t *pool) |
Handling non-file non-directory entries. | |
svn_error_t * | up__set_target_revision (void *edit_baton, svn_revnum_t rev, apr_pool_t *pool) |
svn_error_t * | up__open_root (void *edit_baton, svn_revnum_t base_revision, apr_pool_t *dir_pool UNUSED, void **root_baton) |
svn_error_t * | up__add_directory (const char *utf8_path, void *parent_baton, const char *utf8_copy_path, svn_revnum_t copy_rev, apr_pool_t *dir_pool UNUSED, void **child_baton) |
svn_error_t * | up__change_dir_prop (void *dir_baton, const char *utf8_name, const svn_string_t *value, apr_pool_t *pool) |
svn_error_t * | up__close_directory (void *dir_baton, apr_pool_t *pool) |
svn_error_t * | up__absent_directory (const char *utf8_path, void *parent_baton, apr_pool_t *pool) |
FSVS GCOV MARK: up__absent_directory should not be executed. | |
svn_error_t * | up__add_file (const char *utf8_path, void *parent_baton, const char *utf8_copy_path, svn_revnum_t copy_rev, apr_pool_t *file_pool, void **file_baton) |
svn_error_t * | up__apply_textdelta (void *file_baton, const char *base_checksum, apr_pool_t *pool, svn_txdelta_window_handler_t *handler, void **handler_baton) |
svn_error_t * | up__change_file_prop (void *file_baton, const char *utf8_name, const svn_string_t *value, apr_pool_t *pool) |
svn_error_t * | up__close_file (void *file_baton, const char *text_checksum, apr_pool_t *pool) |
svn_error_t * | up__absent_file (const char *utf8_path, void *parent_baton, apr_pool_t *pool) |
FSVS GCOV MARK: up__absent_file should not be executed. | |
svn_error_t * | up__close_edit (void *edit_baton, apr_pool_t *pool) |
svn_error_t * | up__abort_edit (void *edit_baton, apr_pool_t *pool) |
FSVS GCOV MARK: up__abort_edit should not be executed. | |
int | ac___up_set_paths (struct estat *dir, const svn_ra_reporter2_t *reporter, void *report_baton, apr_pool_t *pool) |
int | up__work (struct estat *root, int argc, char *argv[]) |
Main update action. | |
Variables | |
static char * | filename |
static char * | filename_tmp = NULL |
static unsigned | tmp_len = 0 |
update action.
When we've loaded the "old" version from disk, we fetch the new values from the repository.
Definition in file update.c.
int ac___up_set_paths | ( | struct estat * | dir, | |
const svn_ra_reporter2_t * | reporter, | |||
void * | report_baton, | |||
apr_pool_t * | pool | |||
) |
Definition at line 1098 of file update.c.
References estat::by_inode, DEBUGP, estat::entry_count, estat::entry_status, FS_CHANGED, FS_REMOVED, sstat_t::mode, ops__build_path(), estat::st, STOPIF, and STOPIF_SVNERR.
svn_error_t* up__abort_edit | ( | void * | edit_baton, | |
apr_pool_t * | pool | |||
) |
svn_error_t* up__absent_directory | ( | const char * | utf8_path, | |
void * | parent_baton, | |||
apr_pool_t * | pool | |||
) |
svn_error_t* up__absent_file | ( | const char * | utf8_path, | |
void * | parent_baton, | |||
apr_pool_t * | pool | |||
) |
svn_error_t* up__add_directory | ( | const char * | utf8_path, | |
void * | parent_baton, | |||
const char * | utf8_copy_path, | |||
svn_revnum_t | copy_rev, | |||
apr_pool_t *dir_pool | UNUSED, | |||
void ** | child_baton | |||
) |
Definition at line 711 of file update.c.
References action, cb__add_entry(), hlp__lstat(), actionlist_t::is_compare, RETURN_SVNERR, estat::st, STOPIF, and STOPIF_CODE_ERR.
svn_error_t* up__add_file | ( | const char * | utf8_path, | |
void * | parent_baton, | |||
const char * | utf8_copy_path, | |||
svn_revnum_t | copy_rev, | |||
apr_pool_t * | file_pool, | |||
void ** | file_baton | |||
) |
Definition at line 805 of file update.c.
References cb__add_entry(), RETURN_SVNERR, and STOPIF.
svn_error_t* up__apply_textdelta | ( | void * | file_baton, | |
const char * | base_checksum, | |||
apr_pool_t * | pool, | |||
svn_txdelta_window_handler_t * | handler, | |||
void ** | handler_baton | |||
) |
This is a bit complicated.
With the file:/// protocol, the source and destination filehandles are not closed by the subversion libraries; with svn+ssh:/// they are.
If we just do a apr_file_close(), we get the error EBADF (bad filehandle), and would accordingly die.
If we don't do it (and let apr_pool_cleanup close it), the close may just fall into the next second, and our (in up__close_file) cached ctime is wrong - so we'd mark this entry as changed.
One solution would be to do a apr_file_close(), and ignore EBADF; this is a bit unclean.
So we go the other route: we simply define a subpool, where we allocate the handles in, and clear that later. That has the additional advantage that the struct estat could possibly be shrinked in the future.
Definition at line 823 of file update.c.
References action, cs__new_manber_filter(), DEBUGP, estat::decoder, estat::entry_status, estat::filehandle_pool, filename, filename_tmp, FS_CHANGED, FS_NEW, FS_REMOVED, global_pool, hlp__encode_filter(), hlp__local2utf8(), hlp__realloc(), actionlist_t::is_compare, actionlist_t::is_import_export, estat::md5, sstat_t::mode, ops__build_path(), ops__dev_to_filedata(), ops__link_to_string(), encoder_t::output_md5, estat::remote_status, RETURN_SVNERR, estat::st, STOPIF, STOPIF_CODE_ERR, estat::stringbuf_tgt, and tmp_len.
svn_error_t* up__change_dir_prop | ( | void * | dir_baton, | |
const char * | utf8_name, | |||
const svn_string_t * | value, | |||
apr_pool_t * | pool | |||
) |
Definition at line 750 of file update.c.
References RETURN_SVNERR, STOPIF, up__parse_prop(), estat::url, and url__current_has_precedence().
svn_error_t* up__change_file_prop | ( | void * | file_baton, | |
const char * | utf8_name, | |||
const svn_string_t * | value, | |||
apr_pool_t * | pool | |||
) |
Definition at line 978 of file update.c.
References BUG_ON, FS_CHANGED, estat::remote_status, RETURN_SVNERR, STOPIF, up__parse_prop(), estat::url, and url__current_has_precedence().
svn_error_t* up__close_directory | ( | void * | dir_baton, | |
apr_pool_t * | pool | |||
) |
Definition at line 767 of file update.c.
References filename, estat::flags, hlp__lstat(), ops__build_path(), RETURN_SVNERR, RF_CHECK, estat::st, st__status, STOPIF, and up__set_meta_data().
svn_error_t* up__close_edit | ( | void * | edit_baton, | |
apr_pool_t * | pool | |||
) |
svn_error_t* up__close_file | ( | void * | file_baton, | |
const char * | text_checksum, | |||
apr_pool_t * | pool | |||
) |
Definition at line 998 of file update.c.
References action, BUG_ON, cs__md5tohex_buffered(), DEBUGP, estat::filehandle_pool, filename, filename_tmp, FS_CHANGED, hlp__lstat(), actionlist_t::is_compare, estat::md5, sstat_t::mode, estat::remote_status, RETURN_SVNERR, estat::st, st__status, STOPIF, STOPIF_CODE_ERR, estat::stringbuf_tgt, up__handle_special(), and up__set_meta_data().
int up__fetch_decoder | ( | struct estat * | sts | ) |
Prefetch update-pipe property.
In case we're updating an existing file, we won't get all properties sent - only changed. So we have to look for existing properties if we need them.
Definition at line 99 of file update.c.
References action, estat::decoder, hlp__strdup(), hsh__close(), actionlist_t::needs_decoder, propval_updatepipe, prp__get(), prp__open_byestat(), and STOPIF.
Referenced by cb___open_file(), and rev__install_file().
int up__handle_special | ( | struct estat * | sts, | |
char * | path, | |||
char * | data, | |||
apr_pool_t * | pool | |||
) |
Handling non-file non-directory entries.
We know it's a special file, but not more; we have to take the filedata and retrieve the type.
After this call sts->st.mode
and sts->new_rev_mode_packed
are set to the current value.
Definition at line 634 of file update.c.
References DEBUGP, hlp__utf82local(), estat::local_mode_packed, sstat_t::mode, estat::new_rev_mode_packed, ops__string_to_dev(), PACKED_to_MODE_T, sstat_t::rdev, estat::st, STOPIF, STOPIF_CODE_ERR, and estat::stringbuf_tgt.
Referenced by rev__install_file(), and up__close_file().
svn_error_t* up__open_root | ( | void * | edit_baton, | |
svn_revnum_t | base_revision, | |||
apr_pool_t *dir_pool | UNUSED, | |||
void ** | root_baton | |||
) |
Definition at line 697 of file update.c.
References estat::repos_rev.
int up__parse_prop | ( | struct estat * | sts, | |
const char * | utf8_name, | |||
const svn_string_t * | utf8_value, | |||
int * | not_handled, | |||
apr_pool_t * | pool | |||
) |
-.
Parse subversion properties for the given entry.
If not_handled is not NULL
, it gets set to 1
if this property is not handled; so the caller knows that he has to to write the property into some other storage if he wants to keep it.
0
; pre-populating is left to the caller. Definition at line 145 of file update.c.
References action, BUG_ON, cs__char2md5(), cs__md5tohex_buffered(), DEBUGP, estat::decoder, estat::decoder_is_correct, FS_META_GROUP, FS_META_MTIME, FS_META_OWNER, FS_META_UMODE, FS_PROPERTIES, sstat_t::gid, estat::has_orig_md5, hlp__get_gid(), hlp__get_uid(), hlp__is_special_property_name(), hlp__skip_ws(), hlp__strdup(), hlp__utf82local(), actionlist_t::is_compare, estat::md5, sstat_t::mode, MODE_T_to_PACKED, sstat_t::mtim, estat::name, actionlist_t::needs_decoder, estat::new_rev_mode_packed, ops__build_path(), PACKED_to_MODE_T, propname_group, propname_mtime, propname_origmd5, propname_owner, propname_special, propname_umode, propval_special, propval_updatepipe, estat::remote_status, S_IFANYSPECIAL, S_ISANYSPECIAL, estat::st, STOPIF, TEST_PACKED, sstat_t::uid, wa__warn(), WRN__META_MTIME_INVALID, WRN__META_UMASK_INVALID, and WRN__META_USER_INVALID.
Referenced by cb___store_prop(), prp__set_from_aprhash(), up__change_dir_prop(), and up__change_file_prop().
Recursively delete a directory structure.
Only non-changed, known entries, so we don't remove changed data.
If an entry does not exist (ENOENT), it is ignored.
Only entries that are registered from URLs given on the command line (with -u
) are removed.
If children that belong to other URLs are found we don't remove the directory.
Definition at line 428 of file update.c.
References estat::by_inode, DEBUGP, estat::entry_count, estat::name, ops__build_path(), STOPIF, up__rmdir(), up__unlink(), and estat::url.
Referenced by rev___undo_change(), and up__rmdir().
int up__set_meta_data | ( | struct estat * | sts, | |
char * | filename | |||
) |
-.
The file has current properties, which we'd like to replace with the saved. But all not-set properties should not be modified.
And all settings should be saved in the waa-area _with the current values_, so that this entry won't be seen as modified.
The easy way: We set what we can, and do a stat() afterwards to capture the current setting.
This has a small race condition: If another process changes the meta-data after setting and before querying, we don't see that it was changed.
How it was done previously: We stored a copy of the wanted things, and copy what we set.
So there's no race-condition, except that we change meta-data a process has just changed.
Since svn 1.3.0 we no longer get all properties on an update, only these that are different to the reported version. That means that most times we'll get only the mtime as changed.
Now, if the file has a unix-mode other than 0600
or an owner which is not equal to the current user, we wouldn't set that because the change mask didn't tell to.
So the file would retain the values of the temporary file, which are 0600 and the current user and group.
The new strategy is: write all values. If there are no properties set for a file, we'll just write the values it currently has - so no problem.
With one exception: the ctime will change, and so we'll believe that it has changed next time. So we fetch the real
, current values afterwards.
Meta-data-only changes happen too often, see this case:
N
.M
for this entry. The directory still has N
, because there might be other new entries in-between.T
.N
, file is at M
,M
]. Basically we're saying we have file at M
, and get back changed, last change happened at M
. (Will file a bug report.)So we get a meta-data change, update the meta-data (currently - will change that soon), and have another ctime (but don't update the entries' meta-data), so find the entry as changed ...
Current solution: read back the entries' meta-data after changing it.
Another thought - if we have different meta-data locally, that's possibly something worth preserving. If the owner has changed in the repository and locally, we'd have to flag a conflict! Furthermore the root entry gets no properties, so it gets set to owner 0.0
, mode 0600
... which is not right either.
Definition at line 536 of file update.c.
References CHOWN_BOOL, CHOWN_FUNC, DEBUGP, DEBUGP_dump_estat(), FS_META_GROUP, FS_META_MTIME, FS_META_OWNER, FS_META_UMODE, sstat_t::gid, hlp__lstat(), sstat_t::mode, sstat_t::mtim, estat::new_rev_mode_packed, ops__build_path(), PACKED_to_MODE_T, estat::remote_status, estat::st, STOPIF, STOPIF_CODE_ERR, sstat_t::uid, UTIMES_BOOL, UTIMES_FUNC, wa__warn(), WRN__CHMOD_EPERM, WRN__CHMOD_OTHER, WRN__CHOWN_EPERM, and WRN__CHOWN_OTHER.
Referenced by rev___handle_dir_mtime(), rev___revert_to_base(), rev___undo_change(), rev__install_file(), rev__merge(), up__close_directory(), and up__close_file().
svn_error_t* up__set_target_revision | ( | void * | edit_baton, | |
svn_revnum_t | rev, | |||
apr_pool_t * | pool | |||
) |
Definition at line 678 of file update.c.
References estat::repos_rev, RETURN_SVNERR, and target_revision.
int up__unlink | ( | struct estat * | sts, | |
char * | filename | |||
) |
-.
Remove a (non-dir) file. Must return errors silently.
Definition at line 382 of file update.c.
References DEBUGP, estat::entry_status, FS_CHANGED, ops__build_path(), STOPIF, STOPIF_CODE_ERR, waa__delete_byext(), WAA__FILE_MD5s_EXT, and WAA__PROP_EXT.
Referenced by rev___undo_change(), and up__rmdir().
int up__work | ( | struct estat * | root, | |
int | argc, | |||
char * | argv[] | |||
) |
Main update action.
We do most of the setup before checking the whole tree.
Please note that this is not atomic - use unionfs.
Definition at line 1137 of file update.c.
References action, cb__record_changes(), cb__remove_url(), CHCHECK_FILE, ci__set_revision(), current_url, DEBUGP, DELAY_UPDATE, global_pool, hlp__delay(), actionlist_t::is_compare, OPT__CHANGECHECK, opt__set_int(), opt__verbosity(), url_t::pool, PRIO_MUSTHAVE, rev__do_changed(), STOP_HANDLE_SVNERR, STOPIF, STOPIF_CODE_ERR, url_t::url, url__iterator(), url__load_nonempty_list(), url__mark_todo(), url__output_list(), urllist_count, VERBOSITY_VERYQUIET, waa__find_base(), waa__output_tree(), and waa__read_or_build_tree().
char* filename [static] |
Definition at line 89 of file update.c.
Referenced by cb__add_entry(), ci__nondir(), cs___update_manber(), cs__new_manber_filter(), cs__read_manber_hashes(), delay__work(), hlp__chrooter(), ops__find_entry_byname(), res__mark_conflict(), res__remove_aux_files(), rev__get_props(), rev__install_file(), up__apply_textdelta(), up__close_directory(), up__close_file(), waa__get_tmp_name(), and waa__input_tree().
char * filename_tmp = NULL [static] |
Definition at line 90 of file update.c.
Referenced by rev__install_file(), up__apply_textdelta(), and up__close_file().
unsigned tmp_len = 0 [static] |
Definition at line 91 of file update.c.
Referenced by up__apply_textdelta().