diff options
Diffstat (limited to 'tools/examples/testwrite.c')
-rw-r--r-- | tools/examples/testwrite.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/tools/examples/testwrite.c b/tools/examples/testwrite.c new file mode 100644 index 0000000..beb2fba --- /dev/null +++ b/tools/examples/testwrite.c @@ -0,0 +1,276 @@ +/* + * testwrite.c : test whether a user has commit access. + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * To compile on unix against Subversion and APR libraries, try + * something like: + * + * cc testwrite.c -o testwrite \ + * -I/usr/local/include/subversion-1 -I/usr/local/apache2/include \ + * -L/usr/local/apache2/lib -L/usr/local/lib \ + * -lsvn_client-1 -lsvn_ra-1 -lsvn_subr-1 -lsvn-fs-1 -lapr-0 -laprutil-0 + * + */ + +#include "svn_client.h" +#include "svn_pools.h" +#include "svn_config.h" +#include "svn_fs.h" +#include "svn_cmdline.h" +#include "svn_path.h" +#include "svn_time.h" + + +/* Display a prompt and read a one-line response into the provided buffer, + removing a trailing newline if present. */ +static svn_error_t * +prompt_and_read_line(const char *prompt, + char *buffer, + size_t max) +{ + int len; + printf("%s: ", prompt); + if (fgets(buffer, max, stdin) == NULL) + return svn_error_create(0, NULL, "error reading stdin"); + len = strlen(buffer); + if (len > 0 && buffer[len-1] == '\n') + buffer[len-1] = 0; + return SVN_NO_ERROR; +} + +/* A tiny callback function of type 'svn_auth_simple_prompt_func_t'. For + a much better example, see svn_cl__auth_simple_prompt in the official + svn cmdline client. */ +static svn_error_t * +my_simple_prompt_callback (svn_auth_cred_simple_t **cred, + void *baton, + const char *realm, + const char *username, + svn_boolean_t may_save, + apr_pool_t *pool) +{ + svn_auth_cred_simple_t *ret = apr_pcalloc (pool, sizeof (*ret)); + char answerbuf[100]; + + if (realm) + { + printf ("Authentication realm: %s\n", realm); + } + + if (username) + ret->username = apr_pstrdup (pool, username); + else + { + SVN_ERR (prompt_and_read_line("Username", answerbuf, sizeof(answerbuf))); + ret->username = apr_pstrdup (pool, answerbuf); + } + + SVN_ERR (prompt_and_read_line("Password", answerbuf, sizeof(answerbuf))); + ret->password = apr_pstrdup (pool, answerbuf); + + *cred = ret; + return SVN_NO_ERROR; +} + + +/* A tiny callback function of type 'svn_auth_username_prompt_func_t'. For + a much better example, see svn_cl__auth_username_prompt in the official + svn cmdline client. */ +static svn_error_t * +my_username_prompt_callback (svn_auth_cred_username_t **cred, + void *baton, + const char *realm, + svn_boolean_t may_save, + apr_pool_t *pool) +{ + svn_auth_cred_username_t *ret = apr_pcalloc (pool, sizeof (*ret)); + char answerbuf[100]; + + if (realm) + { + printf ("Authentication realm: %s\n", realm); + } + + SVN_ERR (prompt_and_read_line("Username", answerbuf, sizeof(answerbuf))); + ret->username = apr_pstrdup (pool, answerbuf); + + *cred = ret; + return SVN_NO_ERROR; +} + +/* A callback function used when the RA layer needs a handle to a + temporary file. This is a reduced version of the callback used in + the official svn cmdline client. */ +static svn_error_t * +open_tmp_file (apr_file_t **fp, + void *callback_baton, + apr_pool_t *pool) +{ + const char *path; + const char *ignored_filename; + + SVN_ERR (svn_io_temp_dir (&path, pool)); + path = svn_path_join (path, "tempfile", pool); + + /* Open a unique file, with delete-on-close set. */ + SVN_ERR (svn_io_open_unique_file2 (fp, &ignored_filename, + path, ".tmp", + svn_io_file_del_on_close, pool)); + + return SVN_NO_ERROR; +} + + +/* Called when a commit is successful. */ +static svn_error_t * +my_commit_callback (svn_revnum_t new_revision, + const char *date, + const char *author, + void *baton) +{ + printf ("Upload complete. Committed revision %ld.\n", new_revision); + return SVN_NO_ERROR; +} + + + +int +main (int argc, const char **argv) +{ + apr_pool_t *pool; + svn_error_t *err; + apr_hash_t *dirents; + const char *upload_file, *URL; + const char *parent_URL, *basename; + svn_ra_plugin_t *ra_lib; + void *session, *ra_baton; + svn_revnum_t rev; + const svn_delta_editor_t *editor; + void *edit_baton; + svn_dirent_t *dirent; + svn_ra_callbacks_t *cbtable; + apr_hash_t *cfg_hash; + svn_auth_baton_t *auth_baton; + + if (argc <= 1) + { + printf ("Usage: %s URL\n", argv[0]); + printf (" Tries to create an svn commit-transaction at URL.\n"); + return EXIT_FAILURE; + } + URL = argv[1]; + + /* Initialize the app. Send all error messages to 'stderr'. */ + if (svn_cmdline_init ("minimal_client", stderr) != EXIT_SUCCESS) + return EXIT_FAILURE; + + /* Create top-level memory pool. Be sure to read the HACKING file to + understand how to properly use/free subpools. */ + pool = svn_pool_create (NULL); + + /* Initialize the FS library. */ + err = svn_fs_initialize (pool); + if (err) goto hit_error; + + /* Make sure the ~/.subversion run-time config files exist, and load. */ + err = svn_config_ensure (NULL, pool); + if (err) goto hit_error; + + err = svn_config_get_config (&cfg_hash, NULL, pool); + if (err) goto hit_error; + + /* Build an authentication baton. */ + { + /* There are many different kinds of authentication back-end + "providers". See svn_auth.h for a full overview. */ + svn_auth_provider_object_t *provider; + apr_array_header_t *providers + = apr_array_make (pool, 4, sizeof (svn_auth_provider_object_t *)); + + svn_client_get_simple_prompt_provider (&provider, + my_simple_prompt_callback, + NULL, /* baton */ + 2, /* retry limit */ pool); + APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider; + + svn_client_get_username_prompt_provider (&provider, + my_username_prompt_callback, + NULL, /* baton */ + 2, /* retry limit */ pool); + APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider; + + /* Register the auth-providers into the context's auth_baton. */ + svn_auth_open (&auth_baton, providers, pool); + } + + /* Create a table of callbacks for the RA session, mostly nonexistent. */ + cbtable = apr_pcalloc (pool, sizeof(*cbtable)); + cbtable->auth_baton = auth_baton; + cbtable->open_tmp_file = open_tmp_file; + + /* Now do the real work. */ + + /* Open an RA session to the parent URL, fetch current HEAD rev and + "lock" onto that revnum for the remainder of the session. */ + svn_path_split (URL, &parent_URL, &basename, pool); + + err = svn_ra_init_ra_libs (&ra_baton, pool); + if (err) goto hit_error; + + err = svn_ra_get_ra_library (&ra_lib, ra_baton, parent_URL, pool); + if (err) goto hit_error; + + err = ra_lib->open (&session, parent_URL, cbtable, NULL, cfg_hash, pool); + if (err) goto hit_error; + + /* Fetch a commit editor (it's anchored on the parent URL, because + the session is too.) */ + /* ### someday add an option for a user-written commit message? */ + err = ra_lib->get_commit_editor (session, &editor, &edit_baton, + "File upload from 'svnput' program.", + my_commit_callback, NULL, pool); + if (err) goto hit_error; + + /* Drive the editor */ + { + void *root_baton, *file_baton, *handler_baton; + svn_txdelta_window_handler_t handler; + svn_stream_t *contents; + apr_file_t *f = NULL; + + err = editor->open_root (edit_baton, rev, pool, &root_baton); + if (err) goto hit_error; + + err = editor->abort_edit (edit_baton, pool); + if (err) goto hit_error; + } + + printf ("No problems creating commit transaction.\n"); + return EXIT_SUCCESS; + + hit_error: + { + printf("Could not open a commit transaction.\n"); + svn_handle_error2 (err, stderr, FALSE, "testwrite: "); + return EXIT_FAILURE; + } + +} |