1 /*
2 * getlocks_test.c : show all repository locks living below a URL
3 *
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
20 * under the License.
21 * ====================================================================
22 *
23 * To compile on unix against Subversion and APR libraries, try
24 * something like:
25 *
26 * cc getlocks_test.c -o getlocks_test \
27 * -I/usr/local/include/subversion-1 -I/usr/local/apache2/include \
28 * -L/usr/local/apache2/lib -L/usr/local/lib \
29 * -lsvn_client-1 -lsvn_ra-1 -lsvn_subr-1 -lapr-0 -laprutil-0
30 *
31 */
32
33 #include "svn_client.h"
34 #include "svn_pools.h"
35 #include "svn_config.h"
36 #include "svn_cmdline.h"
37 #include "svn_time.h"
38 #include "svn_fs.h"
39 #include "svn_path.h"
40
41 /* Display a prompt and read a one-line response into the provided buffer,
42 removing a trailing newline if present. */
43 static svn_error_t *
prompt_and_read_line(const char * prompt,char * buffer,size_t max)44 prompt_and_read_line(const char *prompt,
45 char *buffer,
46 size_t max)
47 {
48 int len;
49 printf("%s: ", prompt);
50 if (fgets(buffer, max, stdin) == NULL)
51 return svn_error_create(0, NULL, "error reading stdin");
52 len = strlen(buffer);
53 if (len > 0 && buffer[len-1] == '\n')
54 buffer[len-1] = 0;
55 return SVN_NO_ERROR;
56 }
57
58 /* A tiny callback function of type 'svn_auth_simple_prompt_func_t'. For
59 a much better example, see svn_cl__auth_simple_prompt in the official
60 svn cmdline client. */
61 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)62 my_simple_prompt_callback (svn_auth_cred_simple_t **cred,
63 void *baton,
64 const char *realm,
65 const char *username,
66 svn_boolean_t may_save,
67 apr_pool_t *pool)
68 {
69 svn_auth_cred_simple_t *ret = apr_pcalloc (pool, sizeof (*ret));
70 char answerbuf[100];
71
72 if (realm)
73 {
74 printf ("Authentication realm: %s\n", realm);
75 }
76
77 if (username)
78 ret->username = apr_pstrdup (pool, username);
79 else
80 {
81 SVN_ERR (prompt_and_read_line("Username", answerbuf, sizeof(answerbuf)));
82 ret->username = apr_pstrdup (pool, answerbuf);
83 }
84
85 SVN_ERR (prompt_and_read_line("Password", answerbuf, sizeof(answerbuf)));
86 ret->password = apr_pstrdup (pool, answerbuf);
87
88 *cred = ret;
89 return SVN_NO_ERROR;
90 }
91
92
93 /* A tiny callback function of type 'svn_auth_username_prompt_func_t'. For
94 a much better example, see svn_cl__auth_username_prompt in the official
95 svn cmdline client. */
96 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)97 my_username_prompt_callback (svn_auth_cred_username_t **cred,
98 void *baton,
99 const char *realm,
100 svn_boolean_t may_save,
101 apr_pool_t *pool)
102 {
103 svn_auth_cred_username_t *ret = apr_pcalloc (pool, sizeof (*ret));
104 char answerbuf[100];
105
106 if (realm)
107 {
108 printf ("Authentication realm: %s\n", realm);
109 }
110
111 SVN_ERR (prompt_and_read_line("Username", answerbuf, sizeof(answerbuf)));
112 ret->username = apr_pstrdup (pool, answerbuf);
113
114 *cred = ret;
115 return SVN_NO_ERROR;
116 }
117
118
119 /* A callback function used when the RA layer needs a handle to a
120 temporary file. This is a reduced version of the callback used in
121 the official svn cmdline client. */
122 static svn_error_t *
open_tmp_file(apr_file_t ** fp,void * callback_baton,apr_pool_t * pool)123 open_tmp_file (apr_file_t **fp,
124 void *callback_baton,
125 apr_pool_t *pool)
126 {
127 const char *path;
128 const char *ignored_filename;
129
130 SVN_ERR (svn_io_temp_dir (&path, pool));
131 path = svn_path_join (path, "tempfile", pool);
132
133 /* Open a unique file, with delete-on-close set. */
134 SVN_ERR (svn_io_open_unique_file2 (fp, &ignored_filename,
135 path, ".tmp",
136 svn_io_file_del_on_close, pool));
137
138 return SVN_NO_ERROR;
139 }
140
141
142
143 int
main(int argc,const char ** argv)144 main (int argc, const char **argv)
145 {
146 apr_pool_t *pool;
147 svn_error_t *err;
148 apr_hash_t *locks;
149 apr_hash_index_t *hi;
150 const char *URL;
151 svn_ra_session_t *session;
152 svn_ra_callbacks_t *cbtable;
153 apr_hash_t *cfg_hash;
154 svn_auth_baton_t *auth_baton;
155
156 if (argc <= 1)
157 {
158 printf ("Usage: %s URL\n", argv[0]);
159 printf (" Print all locks at or below URL.\n");
160 return EXIT_FAILURE;
161 }
162 URL = argv[1];
163
164 /* Initialize the app. Send all error messages to 'stderr'. */
165 if (svn_cmdline_init ("ra_test", stderr) != EXIT_SUCCESS)
166 return EXIT_FAILURE;
167
168 /* Create top-level memory pool. Be sure to read the HACKING file to
169 understand how to properly use/free subpools. */
170 pool = svn_pool_create (NULL);
171
172 /* Initialize the FS library. */
173 err = svn_fs_initialize (pool);
174 if (err) goto hit_error;
175
176 /* Make sure the ~/.subversion run-time config files exist, and load. */
177 err = svn_config_ensure (NULL, pool);
178 if (err) goto hit_error;
179
180 err = svn_config_get_config (&cfg_hash, NULL, pool);
181 if (err) goto hit_error;
182
183 /* Build an authentication baton. */
184 {
185 /* There are many different kinds of authentication back-end
186 "providers". See svn_auth.h for a full overview. */
187 svn_auth_provider_object_t *provider;
188 apr_array_header_t *providers
189 = apr_array_make (pool, 4, sizeof (svn_auth_provider_object_t *));
190
191 svn_client_get_simple_prompt_provider (&provider,
192 my_simple_prompt_callback,
193 NULL, /* baton */
194 2, /* retry limit */ pool);
195 APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
196
197 svn_client_get_username_prompt_provider (&provider,
198 my_username_prompt_callback,
199 NULL, /* baton */
200 2, /* retry limit */ pool);
201 APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
202
203 /* Register the auth-providers into the context's auth_baton. */
204 svn_auth_open (&auth_baton, providers, pool);
205 }
206
207 /* Create a table of callbacks for the RA session, mostly nonexistent. */
208 cbtable = apr_pcalloc (pool, sizeof(*cbtable));
209 cbtable->auth_baton = auth_baton;
210 cbtable->open_tmp_file = open_tmp_file;
211
212 /* Now do the real work. */
213
214 err = svn_ra_open (&session, URL, cbtable, NULL, cfg_hash, pool);
215 if (err) goto hit_error;
216
217 err = svn_ra_get_locks (session, &locks, "", pool);
218 if (err) goto hit_error;
219
220 err = svn_cmdline_printf (pool, "\n");
221 if (err) goto hit_error;
222
223 for (hi = apr_hash_first (pool, locks); hi; hi = apr_hash_next (hi))
224 {
225 const void *key;
226 void *val;
227 const char *path, *cr_date, *exp_date;
228 svn_lock_t *lock;
229
230 apr_hash_this (hi, &key, NULL, &val);
231 path = key;
232 lock = val;
233
234 cr_date = svn_time_to_human_cstring (lock->creation_date, pool);
235
236 if (lock->expiration_date)
237 exp_date = svn_time_to_human_cstring (lock->expiration_date, pool);
238 else
239 exp_date = "never";
240
241 err = svn_cmdline_printf (pool, "%s\n", path);
242 if (err) goto hit_error;
243
244 err = svn_cmdline_printf (pool,
245 " UUID Token: %s\n", lock->token);
246 if (err) goto hit_error;
247
248 err = svn_cmdline_printf (pool,
249 " Owner: %s\n", lock->owner);
250 if (err) goto hit_error;
251
252 err = svn_cmdline_printf (pool,
253 " Comment: %s\n",
254 lock->comment ? lock->comment : "none");
255 if (err) goto hit_error;
256
257 err = svn_cmdline_printf (pool,
258 " Created: %s\n", cr_date);
259 if (err) goto hit_error;
260
261 err = svn_cmdline_printf (pool,
262 " Expires: %s\n\n", exp_date);
263 if (err) goto hit_error;
264 }
265
266 return EXIT_SUCCESS;
267
268 hit_error:
269 svn_handle_error2 (err, stderr, FALSE, "getlocks_test: ");
270 return EXIT_FAILURE;
271 }
272