Ejemplo n.º 1
0
/* Subversion delta editor callback */
static svn_error_t *de_delete_entry(const char *path, svn_revnum_t revision, void *parent_baton, apr_pool_t *pool)
{
	de_node_baton_t *node;
	de_node_baton_t *parent = (de_node_baton_t *)parent_baton;
	apr_hash_index_t *hi;
	int pathlen;

	DEBUG_MSG("de_delete_entry(%s@%ld)\n", path, revision);

	/* We can dump this entry directly */
	node = delta_create_node(path, parent);
	node->kind = svn_node_none;
	node->action = 'D';
	node->dump_needed = 1;
#if 0
	if ((err = delta_dump_node(node))) {
		return err;
	}
#endif

	/* This node might be a directory, so clear the data of all children */
	pathlen = strlen(node->path);
	for (hi = rhash_first(pool, delta_hash); hi; hi = rhash_next(hi)) {
		const char *npath;
		char *filename;
		rhash_this(hi, (const void **)(void *)&npath, NULL, (void **)(void *)&filename);
		/* TODO: This is a small hack to make sure the node is a directory */
		if (!strncmp(node->path, npath, pathlen) && (npath[pathlen] == '/')) {
#ifndef DUMP_DEBUG
			apr_file_remove(filename, node->pool);
#endif
			DEBUG_MSG("deleting %s from delta_hash\n", npath);
			rhash_set(delta_hash, npath, APR_HASH_KEY_STRING, NULL, 0);
		}
	}
	for (hi = rhash_first(pool, prop_hash); hi; hi = rhash_next(hi)) {
		const char *npath;
		char *filename;
		rhash_this(hi, (const void **)(void *)&npath, NULL, (void **)(void *)&filename);
		/* TODO: This is a small hack to make sure the node is a directory */
		if (!strncmp(node->path, npath, pathlen) && (npath[pathlen] == '/')) {
#ifndef DUMP_DEBUG
			apr_file_remove(filename, node->pool);
#endif
			DEBUG_MSG("deleting %s from prop_hash\n", npath);
			rhash_set(prop_hash, npath, APR_HASH_KEY_STRING, NULL, 0);
		}
	}
	for (hi = rhash_first(pool, md5_hash); hi; hi = rhash_next(hi)) {
		const char *npath;
		char *md5sum;
		rhash_this(hi, (const void **)(void *)&npath, NULL, (void **)(void *)&md5sum);
		if (!strncmp(node->path, npath, pathlen) && (npath[pathlen] == '/')) {
			DEBUG_MSG("deleting %s from md5_hash\n", npath);
			rhash_set(md5_hash, npath, APR_HASH_KEY_STRING, NULL, 0);
		}
	}

	return SVN_NO_ERROR;
}
Ejemplo n.º 2
0
Archivo: mukv.c Proyecto: epu/rsvndump
/* Deletes a record (from the index, not from the disk) */
int mukv_delete(mukv_t *kv, mdatum_t key)
{
	entry_t *entry = rhash_get(kv->index, key.dptr, key.dsize);
	if (entry) {
		rhash_set(kv->index, key.dptr, key.dsize, NULL, 0);
	}
	return 0;
}
Ejemplo n.º 3
0
/* Writes the properties of a node to a temporary file */
static svn_error_t *delta_write_properties(de_node_baton_t *node)
{
	char *filename;
	apr_file_t *file = NULL;
	apr_status_t status;
	apr_hash_index_t *hi;
	dump_options_t *opts = node->de_baton->opts;
	apr_pool_t *pool = svn_pool_create(node->pool);

	/* Remove the properties that have been deleted from the hash */
	for (hi = apr_hash_first(pool, node->del_properties); hi; hi = apr_hash_next(hi)) {
		const char *key;
		void *value;
		apr_hash_this(hi, (const void **)(void *)&key, NULL, &value);
		apr_hash_set(node->properties, key, APR_HASH_KEY_STRING, NULL);
	}

	/* We don't need to save anything if there are no properties */
	if (apr_hash_count(node->properties) == 0) {
		rhash_set(prop_hash, node->path, APR_HASH_KEY_STRING, NULL, 0);
		svn_pool_destroy(pool);
		return SVN_NO_ERROR;
	}

	/* Create a new temporary file */
	filename = apr_psprintf(node->pool, "%s/XXXXXX", opts->temp_dir);
	status = apr_file_mktemp(&file, filename, APR_CREATE | APR_READ | APR_WRITE | APR_EXCL, pool);
	if (status) {
		apr_pool_t *epool = svn_pool_create(NULL);
		char *errbuf = apr_palloc(epool, ERRBUFFER_SIZE);
		svn_pool_destroy(pool);
		return svn_error_create(status, NULL, apr_strerror(status, errbuf, ERRBUFFER_SIZE));
	}

	property_hash_write(node->properties, file, pool);
	apr_file_close(file);

	rhash_set(prop_hash, node->path, APR_HASH_KEY_STRING, filename, RHASH_VAL_STRING);

	svn_pool_destroy(pool);
	return SVN_NO_ERROR;
}
Ejemplo n.º 4
0
/* Subversion delta editor callback */
static svn_error_t *de_close_edit(void *edit_baton, apr_pool_t *pool)
{
	de_baton_t *de_baton = (de_baton_t *)edit_baton;
	apr_hash_index_t *hi;
	svn_error_t *err;

	/* Recursively dump all nodes touched by this revision */
	if ((err = delta_dump_node_recursive((de_node_baton_t *)de_baton->root_node))) {
		return err;
	}

	/*
	 * There are probably some deleted nodes that haven't been dumped yet.
	 * This will happen if nodes whose parent is a copy destination have been
	 * deleted.
	 */
	for (hi = apr_hash_first(pool, de_baton->log_revision->changed_paths); hi; hi = apr_hash_next(hi)) {
		const char *path;
		svn_log_changed_path_t *log;
		apr_hash_this(hi, (const void **)(void *)&path, NULL, (void **)(void *)&log);
		DEBUG_MSG("Checking %s (%c)\n", path, log->action);
		if (log->action == 'D') {
			/* We can unlink a possible temporary file now */
			char *filename = rhash_get(delta_hash, path, APR_HASH_KEY_STRING);
			if (filename) {
#ifndef DUMP_DEBUG
				apr_file_remove(filename, pool);
#endif
				rhash_set(delta_hash, path, APR_HASH_KEY_STRING, NULL, 0);
			}

			if (apr_hash_get(de_baton->dumped_entries, path, APR_HASH_KEY_STRING) == NULL) {
				de_node_baton_t *node = delta_create_node_no_parent(path, de_baton, pool);
				node->action = log->action;
				node->dump_needed = 1;

				DEBUG_MSG("Post-dumping %s\n", path);
				if ((err = delta_dump_node(node))) {
					return err;
				}
			}
		}
	}

#ifdef USE_TIMING
	DEBUG_MSG("apply_text_delta: %f seconds\n", tm_de_apply_textdelta);
#endif
	return SVN_NO_ERROR;
}
Ejemplo n.º 5
0
Archivo: mukv.c Proyecto: epu/rsvndump
/* Stores a record */
int mukv_store(mukv_t *kv, mdatum_t key, mdatum_t val)
{
	entry_t entry;
	if (fseek(kv->file, 0, SEEK_END) != 0) {
		return errno;
	}
	entry.off = ftell(kv->file);
	entry.size = val.dsize;

	if (fwrite(val.dptr, 1, val.dsize, kv->file) != val.dsize) {
		return errno;
	}

	rhash_set(kv->index, key.dptr, key.dsize, &entry, sizeof(entry_t));
	return 0;
}
Ejemplo n.º 6
0
/* Marks a node as being dumped, i.e. set dump_needed to 0 */
static void delta_mark_node(de_node_baton_t *node)
{
	de_baton_t *de_baton = node->de_baton;
	apr_hash_set(de_baton->dumped_entries, apr_pstrdup(de_baton->revision_pool, node->path), APR_HASH_KEY_STRING, de_baton /* The value doesn't matter */);
	if (node->kind == svn_node_file) {
		rhash_set(md5_hash, node->path, APR_HASH_KEY_STRING, node->md5sum, APR_MD5_DIGESTSIZE);
		DEBUG_MSG("md5_hash += %s : %s\n", node->path, svn_md5_digest_to_cstring(node->md5sum, node->pool));
	}
	node->dump_needed = 0;

	if ((de_baton->opts->verbosity > 0) && !(de_baton->opts->flags & DF_DRY_RUN)) {
		if (node->cp_info == CPI_COPY) {
			fprintf(stderr, _("COPIED ... done.\n"));
		} else {
			fprintf(stderr, _("done.\n"));
		}
	}
}
Ejemplo n.º 7
0
/* Subversion delta editor callback */
static svn_error_t *de_apply_textdelta(void *file_baton, const char *base_checksum, apr_pool_t *pool, svn_txdelta_window_handler_t *handler, void **handler_baton)
{
	apr_file_t *src_file = NULL, *dest_file = NULL;
	svn_stream_t *src_stream, *dest_stream;
	de_node_baton_t *node = (de_node_baton_t *)file_baton;
	dump_options_t *opts = node->de_baton->opts;
#ifdef USE_TIMING
	stopwatch_t watch = stopwatch_create();
#endif
	char *filename;

	DEBUG_MSG("de_apply_textdelta(%s)\n", node->path);

	/* Create a new temporary file to write to */
	node->filename = apr_psprintf(node->pool, "%s/XXXXXX", opts->temp_dir);
	apr_file_mktemp(&dest_file, node->filename, APR_CREATE | APR_READ | APR_WRITE | APR_EXCL, pool);
	dest_stream = svn_stream_from_aprfile2(dest_file, FALSE, pool);

	/* Update the local copy */
	filename = rhash_get(delta_hash, node->path, APR_HASH_KEY_STRING);
	if (filename == NULL) {
		src_stream = svn_stream_empty(pool);
	} else {
		apr_file_open(&src_file, filename, APR_READ, 0600, pool);
		src_stream = svn_stream_from_aprfile2(src_file, FALSE, pool);
	}

	svn_txdelta_apply(src_stream, dest_stream, node->md5sum, node->path, pool, handler, handler_baton);

	node->old_filename = apr_pstrdup(node->pool, filename);
	rhash_set(delta_hash, node->path, APR_HASH_KEY_STRING, node->filename, RHASH_VAL_STRING);

	DEBUG_MSG("applied delta: %s -> %s\n", node->old_filename, node->filename);

	node->applied_delta = 1;
	node->dump_needed = 1;

#ifdef USE_TIMING
	tm_de_apply_textdelta += stopwatch_elapsed(&watch);
#endif
	return SVN_NO_ERROR;
}
Ejemplo n.º 8
0
/* Loads the properties of a node to a temporary file */
static svn_error_t *delta_load_properties(de_node_baton_t *node)
{
	char *filename;
	apr_file_t *file = NULL;
	apr_status_t status;
	apr_pool_t *pool = svn_pool_create(node->pool);

	filename = rhash_get(prop_hash, node->path, APR_HASH_KEY_STRING);
	if (filename == NULL) {
		/* No properties is ok, too */
		svn_pool_destroy(pool);
		return SVN_NO_ERROR;
	}

	status = apr_file_open(&file, filename, APR_READ, 0600, pool);
	if (status) {
		apr_pool_t *epool = svn_pool_create(NULL);
		char *errbuf = apr_palloc(epool, ERRBUFFER_SIZE);
		svn_pool_destroy(pool);
		return svn_error_create(status, NULL, apr_strerror(status, errbuf, ERRBUFFER_SIZE));
	}

	if (property_hash_load(node->properties, file, node->pool)) {
		apr_file_close(file);
		DEBUG_MSG("ERROR reading from %s\n", filename);
		return svn_error_create(1, NULL, "Error reading properties file");
	}
	apr_file_close(file);

	/* Delete the old file if it exists */
	apr_file_remove(filename, pool);
	rhash_set(prop_hash, node->path, APR_HASH_KEY_STRING, NULL, 0);

	svn_pool_destroy(pool);
	return SVN_NO_ERROR;
}