Move the long option name enum from cl.h into main.c, because it is
[svn.git] / tools / examples / minimal_client.c
blobd7745cc7853c45086bb691e303dd2f6cd3a9caf5
1 /*
2 * minimal_client.c - a minimal Subversion client application ("hello world")
4 * ====================================================================
5 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
18 * This app demonstrates how to use the svn_client.h API.
20 * It reads a directory URL from the commandline, runs
21 * svn_client_list() and prints the list of directory-entries. It
22 * also knows how to deal with basic username/password authentication
23 * challenges.
25 * For a much more complex example, the svn cmdline client might be
26 * considered the 'reference implementation'.
28 * From a Linux system, a typical commandline compile might look like:
30 * cc minimal_client.c -o minimal_client \
31 * -I/usr/local/include/subversion-1 -I/usr/local/apache2/include \
32 * -L/usr/local/apache2/lib -L/usr/local/lib \
33 * -lsvn_client-1 -lapr-0 -laprutil-0
38 #include "svn_client.h"
39 #include "svn_cmdline.h"
40 #include "svn_pools.h"
41 #include "svn_config.h"
42 #include "svn_fs.h"
45 /* Display a prompt and read a one-line response into the provided buffer,
46 removing a trailing newline if present. */
47 static svn_error_t *
48 prompt_and_read_line(const char *prompt,
49 char *buffer,
50 size_t max)
52 int len;
53 printf("%s: ", prompt);
54 if (fgets(buffer, max, stdin) == NULL)
55 return svn_error_create(0, NULL, "error reading stdin");
56 len = strlen(buffer);
57 if (len > 0 && buffer[len-1] == '\n')
58 buffer[len-1] = 0;
59 return SVN_NO_ERROR;
62 /* A tiny callback function of type 'svn_auth_simple_prompt_func_t'. For
63 a much better example, see svn_cl__auth_simple_prompt in the official
64 svn cmdline client. */
65 static svn_error_t *
66 my_simple_prompt_callback (svn_auth_cred_simple_t **cred,
67 void *baton,
68 const char *realm,
69 const char *username,
70 svn_boolean_t may_save,
71 apr_pool_t *pool)
73 svn_auth_cred_simple_t *ret = apr_pcalloc (pool, sizeof (*ret));
74 char answerbuf[100];
76 if (realm)
78 printf ("Authentication realm: %s\n", realm);
81 if (username)
82 ret->username = apr_pstrdup (pool, username);
83 else
85 SVN_ERR (prompt_and_read_line("Username", answerbuf, sizeof(answerbuf)));
86 ret->username = apr_pstrdup (pool, answerbuf);
89 SVN_ERR (prompt_and_read_line("Password", answerbuf, sizeof(answerbuf)));
90 ret->password = apr_pstrdup (pool, answerbuf);
92 *cred = ret;
93 return SVN_NO_ERROR;
97 /* A tiny callback function of type 'svn_auth_username_prompt_func_t'. For
98 a much better example, see svn_cl__auth_username_prompt in the official
99 svn cmdline client. */
100 static svn_error_t *
101 my_username_prompt_callback (svn_auth_cred_username_t **cred,
102 void *baton,
103 const char *realm,
104 svn_boolean_t may_save,
105 apr_pool_t *pool)
107 svn_auth_cred_username_t *ret = apr_pcalloc (pool, sizeof (*ret));
108 char answerbuf[100];
110 if (realm)
112 printf ("Authentication realm: %s\n", realm);
115 SVN_ERR (prompt_and_read_line("Username", answerbuf, sizeof(answerbuf)));
116 ret->username = apr_pstrdup (pool, answerbuf);
118 *cred = ret;
119 return SVN_NO_ERROR;
125 main (int argc, const char **argv)
127 apr_pool_t *pool;
128 svn_error_t *err;
129 svn_opt_revision_t revision;
130 apr_hash_t *dirents;
131 apr_hash_index_t *hi;
132 svn_client_ctx_t *ctx;
133 const char *URL;
135 if (argc <= 1)
137 printf ("Usage: %s URL\n", argv[0]);
138 return EXIT_FAILURE;
140 else
141 URL = argv[1];
143 /* Initialize the app. Send all error messages to 'stderr'. */
144 if (svn_cmdline_init ("minimal_client", stderr) != EXIT_SUCCESS)
145 return EXIT_FAILURE;
147 /* Create top-level memory pool. Be sure to read the HACKING file to
148 understand how to properly use/free subpools. */
149 pool = svn_pool_create (NULL);
151 /* Initialize the FS library. */
152 err = svn_fs_initialize (pool);
153 if (err)
155 /* For functions deeper in the stack, we usually use the
156 SVN_ERR() exception-throwing macro (see svn_error.h). At the
157 top level, we catch & print the error with svn_handle_error2(). */
158 svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
159 return EXIT_FAILURE;
162 /* Make sure the ~/.subversion run-time config files exist */
163 err = svn_config_ensure (NULL, pool);
164 if (err)
166 svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
167 return EXIT_FAILURE;
170 /* All clients need to fill out a client_ctx object. */
172 /* Initialize and allocate the client_ctx object. */
173 if ((err = svn_client_create_context (&ctx, pool)))
175 svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
176 return EXIT_FAILURE;
179 /* Load the run-time config file into a hash */
180 if ((err = svn_config_get_config (&(ctx->config), NULL, pool)))
182 svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
183 return EXIT_FAILURE;
186 #ifdef WIN32
187 /* Set the working copy administrative directory name. */
188 if (getenv ("SVN_ASP_DOT_NET_HACK"))
190 err = svn_wc_set_adm_dir ("_svn", pool);
191 if (err)
193 svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
194 return EXIT_FAILURE;
197 #endif
199 /* Depending on what your client does, you'll want to read about
200 (and implement) the various callback function types below. */
202 /* A func (& context) which receives event signals during
203 checkouts, updates, commits, etc. */
204 /* ctx->notify_func = my_notification_func;
205 ctx->notify_baton = NULL; */
207 /* A func (& context) which can receive log messages */
208 /* ctx->log_msg_func = my_log_msg_receiver_func;
209 ctx->log_msg_baton = NULL; */
211 /* A func (& context) which checks whether the user cancelled */
212 /* ctx->cancel_func = my_cancel_checking_func;
213 ctx->cancel_baton = NULL; */
215 /* Make the client_ctx capable of authenticating users */
217 /* There are many different kinds of authentication back-end
218 "providers". See svn_auth.h for a full overview.
220 If you want to get the auth behavior of the 'svn' program,
221 you can use svn_cmdline_setup_auth_baton, which will give
222 you the exact set of auth providers it uses. This program
223 doesn't use it because it's only appropriate for a command
224 line program, and this is supposed to be a general purpose
225 example. */
227 svn_auth_provider_object_t *provider;
228 apr_array_header_t *providers
229 = apr_array_make (pool, 4, sizeof (svn_auth_provider_object_t *));
231 svn_auth_get_simple_prompt_provider (&provider,
232 my_simple_prompt_callback,
233 NULL, /* baton */
234 2, /* retry limit */ pool);
235 APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
237 svn_auth_get_username_prompt_provider (&provider,
238 my_username_prompt_callback,
239 NULL, /* baton */
240 2, /* retry limit */ pool);
241 APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
243 /* Register the auth-providers into the context's auth_baton. */
244 svn_auth_open (&ctx->auth_baton, providers, pool);
246 } /* end of client_ctx setup */
249 /* Now do the real work. */
251 /* Set revision to always be the HEAD revision. It could, however,
252 be set to a specific revision number, date, or other values. */
253 revision.kind = svn_opt_revision_head;
255 /* Main call into libsvn_client does all the work. */
256 err = svn_client_ls (&dirents,
257 URL, &revision,
258 FALSE, /* no recursion */
259 ctx, pool);
260 if (err)
262 svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
263 return EXIT_FAILURE;
266 /* Print the dir entries in the hash. */
267 for (hi = apr_hash_first (pool, dirents); hi; hi = apr_hash_next (hi))
269 const char *entryname;
270 svn_dirent_t *val;
272 apr_hash_this (hi, (void *) &entryname, NULL, (void *) &val);
273 printf (" %s\n", entryname);
275 /* 'val' is actually an svn_dirent_t structure; a more complex
276 program would mine it for extra printable information. */
279 return EXIT_SUCCESS;