📄 main.c
字号:
/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_recover(apr_getopt_t *os, void *baton, apr_pool_t *pool){ svn_revnum_t youngest_rev; svn_repos_t *repos; svn_error_t *err; struct svnadmin_opt_state *opt_state = baton; /* Restore default signal handlers until after we have acquired the * exclusive lock so that the user interrupt before we actually * touch the repository. */ setup_cancellation_signals(SIG_DFL); err = svn_repos_recover2(opt_state->repository_path, TRUE, recovery_started, pool, pool); if (err) { if (! APR_STATUS_IS_EAGAIN(err->apr_err)) return err; svn_error_clear(err); if (! opt_state->wait) return svn_error_create(SVN_ERR_REPOS_LOCKED, NULL, _("Failed to get exclusive repository " "access; perhaps another process\n" "such as httpd, svnserve or svn " "has it open?")); SVN_ERR(svn_cmdline_printf(pool, _("Waiting on repository lock; perhaps" " another process has it open?\n"))); SVN_ERR(svn_cmdline_fflush(stdout)); SVN_ERR(svn_repos_recover2(opt_state->repository_path, FALSE, recovery_started, pool, pool)); } SVN_ERR(svn_cmdline_printf(pool, _("\nRecovery completed.\n"))); /* Since db transactions may have been replayed, it's nice to tell people what the latest revision is. It also proves that the recovery actually worked. */ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); SVN_ERR(svn_fs_youngest_rev(&youngest_rev, svn_repos_fs(repos), pool)); SVN_ERR(svn_cmdline_printf(pool, _("The latest repos revision is %ld.\n"), youngest_rev)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *list_dblogs(apr_getopt_t *os, void *baton, svn_boolean_t only_unused, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; apr_array_header_t *logfiles; int i; SVN_ERR(svn_repos_db_logfiles(&logfiles, opt_state->repository_path, only_unused, pool)); /* Loop, printing log files. We append the log paths to the repository path, making sure to return everything to the native style before printing. */ for (i = 0; i < logfiles->nelts; i++) { const char *log_utf8; log_utf8 = svn_path_join(opt_state->repository_path, APR_ARRAY_IDX(logfiles, i, const char *), pool); log_utf8 = svn_path_local_style(log_utf8, pool); SVN_ERR(svn_cmdline_printf(pool, "%s\n", log_utf8)); } return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_list_dblogs(apr_getopt_t *os, void *baton, apr_pool_t *pool){ SVN_ERR(list_dblogs(os, baton, FALSE, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_list_unused_dblogs(apr_getopt_t *os, void *baton, apr_pool_t *pool){ SVN_ERR(list_dblogs(os, baton, TRUE, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_rmtxns(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_fs_t *fs; svn_fs_txn_t *txn; apr_array_header_t *args; int i; apr_pool_t *subpool = svn_pool_create(pool); SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); fs = svn_repos_fs(repos); SVN_ERR(svn_opt_parse_all_args(&args, os, pool)); /* All the rest of the arguments are transaction names. */ for (i = 0; i < args->nelts; i++) { const char *txn_name = APR_ARRAY_IDX(args, i, const char *); const char *txn_name_utf8; svn_error_t *err; svn_pool_clear(subpool); SVN_ERR(svn_utf_cstring_to_utf8(&txn_name_utf8, txn_name, subpool)); /* Try to open the txn. If that succeeds, try to abort it. */ err = svn_fs_open_txn(&txn, fs, txn_name_utf8, subpool); if (! err) err = svn_fs_abort_txn(txn, subpool); /* If either the open or the abort of the txn fails because that transaction is dead, just try to purge the thing. Else, there was either an error worth reporting, or not error at all. */ if (err && (err->apr_err == SVN_ERR_FS_TRANSACTION_DEAD)) { svn_error_clear(err); err = svn_fs_purge_txn(fs, txn_name_utf8, subpool); } /* If we had a real from the txn open, abort, or purge, we clear that error and just report to the user that we had an issue with this particular txn. */ if (err) { svn_handle_error2(err, stderr, FALSE /* non-fatal */, "svnadmin: "); svn_error_clear(err); } else if (! opt_state->quiet) { SVN_ERR (svn_cmdline_printf(subpool, _("Transaction '%s' removed.\n"), txn_name)); } } svn_pool_destroy(subpool); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_setlog(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_stringbuf_t *file_contents; const char *filename_utf8; apr_array_header_t *args; svn_string_t *log_contents = svn_string_create("", pool); if (opt_state->start_revision.kind != svn_opt_revision_number) return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("Missing revision")); else if (opt_state->end_revision.kind != svn_opt_revision_unspecified) return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("Only one revision allowed")); SVN_ERR(svn_opt_parse_all_args(&args, os, pool)); if (args->nelts != 1) return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("Exactly one file argument required")); SVN_ERR(svn_utf_cstring_to_utf8(&filename_utf8, APR_ARRAY_IDX(args, 0, const char *), pool)); filename_utf8 = svn_path_internal_style(filename_utf8, pool); SVN_ERR(svn_stringbuf_from_file(&file_contents, filename_utf8, pool)); log_contents->data = file_contents->data; log_contents->len = file_contents->len; SVN_ERR(svn_subst_translate_string(&log_contents, log_contents, NULL, pool)); /* Open the filesystem */ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); /* If we are bypassing the hooks system, we just hit the filesystem directly. */ if (opt_state->bypass_hooks) { svn_fs_t *fs = svn_repos_fs(repos); SVN_ERR(svn_fs_change_rev_prop (fs, opt_state->start_revision.value.number, SVN_PROP_REVISION_LOG, log_contents, pool)); } else { SVN_ERR(svn_repos_fs_change_rev_prop2 (repos, opt_state->start_revision.value.number, NULL, SVN_PROP_REVISION_LOG, log_contents, NULL, NULL, pool)); } return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_verify(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_stream_t *stderr_stream = NULL; svn_revnum_t youngest; /* This whole process is basically just a dump of the repository with no interest in the output. */ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); SVN_ERR(svn_fs_youngest_rev(&youngest, svn_repos_fs(repos), pool)); /* Progress feedback goes to STDERR. */ stderr_stream = recode_stream_create(stderr, pool); SVN_ERR(svn_repos_dump_fs2(repos, NULL, stderr_stream, 0, youngest, FALSE, FALSE, check_cancel, NULL, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */svn_error_t *subcommand_hotcopy(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; SVN_ERR(svn_repos_hotcopy(opt_state->repository_path, opt_state->new_repository_path, opt_state->clean_logs, pool)); return SVN_NO_ERROR;}static svn_error_t *subcommand_lslocks(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_fs_t *fs; apr_hash_t *locks; apr_hash_index_t *hi; SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); fs = svn_repos_fs(repos); /* Fetch all locks on or below the root directory. */ SVN_ERR(svn_repos_fs_get_locks(&locks, repos, "/", NULL, NULL, pool)); for (hi = apr_hash_first(pool, locks); hi; hi = apr_hash_next(hi)) { const void *key; void *val; const char *path, *cr_date, *exp_date = ""; svn_lock_t *lock; int comment_lines = 0; apr_hash_this(hi, &key, NULL, &val); path = key; lock = val; cr_date = svn_time_to_human_cstring(lock->creation_date, pool); if (lock->expiration_date) exp_date = svn_time_to_human_cstring(lock->expiration_date, pool); if (lock->comment) comment_lines = svn_cstring_count_newlines(lock->comment) + 1; SVN_ERR(svn_cmdline_printf(pool, _("Path: %s\n"), path)); SVN_ERR(svn_cmdline_printf(pool, _("UUID Token: %s\n"), lock->token)); SVN_ERR(svn_cmdline_printf(pool, _("Owner: %s\n"), lock->owner)); SVN_ERR(svn_cmdline_printf(pool, _("Created: %s\n"), cr_date)); SVN_ERR(svn_cmdline_printf(pool, _("Expires: %s\n"), exp_date)); SVN_ERR(svn_cmdline_printf(pool, (comment_lines != 1) ? _("Comment (%i lines):\n%s\n\n") : _("Comment (%i line):\n%s\n\n"), comment_lines, lock->comment ? lock->comment : "")); } return SVN_NO_ERROR;}static svn_error_t *subcommand_rmlocks(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_fs_t *fs; svn_fs_access_t *access; svn_error_t *err; apr_array_header_t *args; int i; const char *username; apr_pool_t *subpool = svn_pool_create(pool); SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); fs = svn_repos_fs(repos); /* svn_fs_unlock() demands that some username be associated with the filesystem, so just use the UID of the person running 'svnadmin'.*/ username = svn_user_get_name(pool); if (! username) username = "administrator"; /* Create an access context describing the current user. */ SVN_ERR(svn_fs_create_access(&access, username, pool)); /* Attach the access context to the filesystem. */ SVN_ERR(svn_fs_set_access(fs, access)); /* Parse out any options. */ SVN_ERR(svn_opt_parse_all_args(&args, os, pool)); /* All the rest of the arguments are lock names. */ for (i = 0; i < args->nelts; i++) { const char *lock_path = APR_ARRAY_IDX(args, i, const char *); const char *lock_path_utf8; svn_lock_t *lock; SVN_ERR(svn_utf_cstring_to_utf8(&lock_path_utf8, lock_path, subpool)); /* Fetch the path's svn_lock_t. */ err = svn_fs_get_lock(&lock, fs, lock_path_utf8, subpool); if (err) goto move_on; if (! lock) { SVN_ERR(svn_cmdline_printf(subpool, _("Path '%s' isn't locked.\n"), lock_path)); continue; } /* Now forcibly destroy the lock. */ err = svn_fs_unlock(fs, lock_path_utf8, lock->token, 1 /* force */, subpool); if (err) goto move_on; SVN_ERR(svn_cmdline_printf(subpool, _("Removed lock on '%s'.\n"), lock->path));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -