source: project/svn-client/tags/0.7/svn-client.scm @ 3516

Last change on this file since 3516 was 3515, checked in by azul, 13 years ago

Fixing memory leaks in the error handling code.

File size: 19.5 KB
Line 
1(declare (foreign-declare #<<EOF
2#include <apr.h>
3#include <apr_hash.h>
4#include <apr_file_io.h>
5#include <apr_pools.h>
6#include <svn_auth.h>
7#include <svn_client.h>
8#include <svn_path.h>
9#include <svn_pools.h>
10#include <svn_config.h>
11#include <sys/file.h>
12#include <sys/stat.h>
13#include <sys/types.h>
14#include <unistd.h>
15#include <errno.h>
16
17static svn_opt_revision_t revision_head;
18static svn_opt_revision_t revision_unspecified;
19
20char *svnwiki_user, *svnwiki_pass;
21apr_pool_t *svn_pool;
22svn_client_ctx_t *svn_ctx;
23
24svn_error_t *
25svnwiki_simple_first_credentials (void **credentials, void **iter_baton, void *provider_baton, apr_hash_t *parameters, const char *realmstring, apr_pool_t *pool)
26{
27  svn_auth_cred_simple_t *cred;
28  *credentials = cred = apr_pcalloc(pool, sizeof(svn_auth_cred_simple_t));
29  cred->username = svnwiki_user;
30  cred->password = svnwiki_pass;
31  cred->may_save = 0;
32  return 0;
33}
34
35svn_error_t *
36svnwiki_username_first_credentials (void **credentials, void **iter_baton, void *provider_baton, apr_hash_t *parameters, const char *realmstring, apr_pool_t *pool)
37{
38  svn_auth_cred_username_t *cred;
39  *credentials = cred = apr_pcalloc(pool, sizeof(svn_auth_cred_simple_t));
40  cred->username = svnwiki_user;
41  cred->may_save = 0;
42  return 0;
43}
44
45svn_error_t *
46svnwiki_log_callback (const char **log_msg, const char **tmp_file, apr_array_header_t *commit_items, void *baton, apr_pool_t *pool)
47{
48  *tmp_file = NULL;
49  *log_msg = baton;
50  return SVN_NO_ERROR;
51}
52
53svn_auth_provider_t svnwiki_auth_simple   = { SVN_AUTH_CRED_SIMPLE, svnwiki_simple_first_credentials, NULL, NULL };
54svn_auth_provider_object_t svnwiki_auth_simple_obj = { &svnwiki_auth_simple, NULL };
55
56svn_auth_provider_t svnwiki_auth_username = { SVN_AUTH_CRED_USERNAME, svnwiki_username_first_credentials, NULL, NULL };
57svn_auth_provider_object_t svnwiki_auth_username_obj = { &svnwiki_auth_username, NULL };
58EOF
59))
60
61;;; Pools
62
63(define-record apr-pool ptr)
64
65(define-foreign-type
66  apr-pool-type
67  (pointer "apr_pool_t")
68  apr-pool-ptr
69  make-apr-pool)
70
71(define svn-pool-create
72  (foreign-lambda apr-pool-type "svn_pool_create" apr-pool-type))
73
74;;; Hashes
75
76(define-record apr-hash ptr)
77
78(define-foreign-type
79  apr-hash-type
80  (pointer "apr_hash_t")
81  apr-hash-ptr
82  make-apr-hash)
83
84(define-record apr-hash-index ptr)
85
86(define-foreign-type
87  apr-hash-index-type
88  (pointer "apr_hash_index_t")
89  apr-hash-index-ptr
90  make-apr-hash-index)
91
92(define apr-hash-first
93  (foreign-lambda* apr-hash-index-type ((apr-hash-type hash))
94  "return(apr_hash_first(svn_pool, hash));"))
95
96(define apr-hash-next
97  (foreign-lambda* apr-hash-index-type ((apr-hash-index-type index)) #<<EOF
98  return(apr_hash_next(index));
99EOF
100))
101  ;(foreign-lambda apr-hash-index-type "apr_hash_next" apr-hash-index-type))
102
103(define-external (apr_hash_this_inner ((pointer void) key) (long len) ((pointer void) value)) scheme-object
104  (list key len value))
105
106(define apr-hash-this
107  (foreign-lambda* void ((apr-hash-index-type index)) #<<EOF
108  const void *key;
109  apr_ssize_t keylen;
110  void *value;
111  apr_hash_this(index, &key, &keylen, &value);
112  return(apr_hash_this_inner(key, keylen, value));
113EOF
114))
115
116;;; Errors
117
118(define-record svn-error ptr)
119
120(define-foreign-type
121  svn-error-type
122  (pointer "svn_error_t")
123  svn-error-ptr
124  make-svn-error)
125
126(define svn-no-error
127  (foreign-value "SVN_NO_ERROR" svn-error-type))
128
129;;; Init
130
131((foreign-lambda* c-pointer () #<<EOF
132  apr_array_header_t *providers;
133
134  apr_initialize();
135  svn_pool = svn_pool_create(NULL);
136  svn_config_ensure(NULL, svn_pool);
137
138  svn_client_create_context(&svn_ctx, svn_pool);
139  svn_config_get_config(&svn_ctx->config, NULL, svn_pool);
140
141  providers = apr_array_make(svn_pool, 2, sizeof(svn_auth_provider_object_t *));
142
143  *(svn_auth_provider_object_t **)apr_array_push(providers) = &svnwiki_auth_simple_obj;
144  *(svn_auth_provider_object_t **)apr_array_push(providers) = &svnwiki_auth_username_obj;
145
146  svn_auth_open(&svn_ctx->auth_baton, providers, svn_pool);
147
148  revision_head.kind = svn_opt_revision_head;
149  revision_unspecified.kind = svn_opt_revision_unspecified;
150
151  return(NULL);
152EOF
153))
154
155;;; Info
156
157(define-record svn-info ptr)
158
159;(define (make-svn-info-with-finalizer x)
160;  (set-finalizer! x (foreign-lambda void "free" (pointer "svn_info_t")))
161;  (make-svn-info x))
162
163(define-foreign-type
164  svn-info-type
165  (pointer "svn_info_t")
166  svn-info-ptr
167  ;make-svn-info-with-finalizer)
168  make-svn-info)
169
170(define svn-info-url
171  (foreign-lambda* c-string ((svn-info-type info))
172#<<EOF
173  return(info->URL);
174EOF
175))
176
177(define svn-info-repos-root-url
178  (foreign-lambda* c-string ((svn-info-type info))
179#<<EOF
180  return(info->repos_root_URL);
181EOF
182))
183
184(define svn-info-rev
185  (foreign-lambda* long ((svn-info-type info))
186#<<EOF
187  return(info->rev);
188EOF
189))
190
191;;; Revisions
192
193(define-record svn-opt-revision ptr)
194
195(define (make-svn-opt-revision-with-finalizer x)
196  (set-finalizer! x (foreign-lambda void "free" (pointer "svn_opt_revision_t")))
197  (make-svn-opt-revision x))
198
199(define-foreign-type
200  svn-opt-revision-type
201  (pointer "svn_opt_revision_t")
202  svn-opt-revision-ptr
203  make-svn-opt-revision-with-finalizer)
204
205(define make-svn-opt-revision-number
206  (foreign-lambda* svn-opt-revision-type ((long num))
207#<<EOF
208  svn_opt_revision_t *rev = malloc(sizeof(svn_opt_revision_t));
209  if (rev)
210    {
211      rev->kind = svn_opt_revision_number;
212      rev->value.number = num;
213    }
214  return(rev);
215EOF
216))
217
218(define svn-opt-revision-head
219  (make-svn-opt-revision (foreign-value "&revision_head" (pointer "svn_opt_revision_t"))))
220
221(define svn-opt-revision-unspecified
222  (make-svn-opt-revision (foreign-value "&revision_unspecified" (pointer "svn_opt_revision_t"))))
223
224(define svn-opt-revision-number
225  (foreign-lambda* long ((svn-opt-revision-type rev))
226#<<EOF
227  return(rev->kind == svn_opt_revision_number ? rev->value.number : -1);
228EOF
229))
230
231(define svn-opt-revision-kind
232  (foreign-lambda* unsigned-int ((svn-opt-revision-type rev))
233#<<EOF
234  return(rev->kind);
235EOF
236))
237
238(define-foreign-type svn-revnum-type long)
239
240;;; svn_log_changed_path_t
241
242(define-record svn-log-changed-path ptr)
243
244(define (make-svn-log-changed-path-with-finalizer x)
245  (set-finalizer! x
246    (foreign-lambda* void (((pointer "svn_log_changed_path_t") obj))
247      "if (obj) free(obj->copyfrom_path); free(obj);"))
248  (make-svn-log-changed-path x))
249
250(define-foreign-type
251  svn-log-changed-path-type
252  (pointer "svn_log_changed_path_t")
253  svn-log-changed-path-ptr
254  make-svn-log-changed-path-with-finalizer)
255
256(define svn-log-changed-path-action
257  (foreign-lambda* char ((svn-log-changed-path-type info))
258#<<EOF
259    return(info->action);
260EOF
261))
262
263(define svn-log-changed-path-copy-from-path
264  (foreign-lambda* c-string ((svn-log-changed-path-type info))
265#<<EOF
266    return(info->copyfrom_path);
267EOF
268))
269
270(define svn-log-changed-path-copy-from-rev
271  (foreign-lambda* long ((svn-log-changed-path-type info))
272#<<EOF
273    return(info->copyfrom_rev);
274EOF
275))
276
277;;; Other stuff
278
279(define svn-commit
280  (foreign-lambda* scheme-object ((c-string path) (c-string user) (c-string pass) (c-string changes))
281#<<EOF
282  svn_client_commit_info_t *commit_info = NULL;
283  apr_array_header_t *targets = apr_array_make(svn_pool, 1, sizeof(char *));
284  svn_error_t *err;
285
286  (*((const char **) apr_array_push (targets))) = path;
287
288  svnwiki_user = user;
289  svnwiki_pass = pass;
290
291  svn_ctx->log_msg_func = svnwiki_log_callback;
292  svn_ctx->log_msg_baton = changes;
293
294  err = svn_client_commit(&commit_info, targets, FALSE, svn_ctx, svn_pool);
295  if (err)
296    {
297      svn_handle_error(err, stderr, FALSE);
298      svn_error_clear(err);
299      return(C_SCHEME_FALSE);
300    }
301  if (!commit_info || commit_info->revision == SVN_INVALID_REVNUM)
302    return(C_SCHEME_TRUE);
303  return(C_fix(commit_info->revision));
304EOF
305))
306
307(define svn-update
308  (foreign-lambda* scheme-object ((c-string url) (c-string path) (svn-opt-revision-type rev) (c-string user) (c-string pass))
309#<<EOF
310  svn_revnum_t revnum;
311  svn_error_t *err;
312
313  svnwiki_user = user;
314  svnwiki_pass = pass;
315
316  err = svn_client_checkout(&revnum, url, path, rev, TRUE, svn_ctx, svn_pool);
317  if (err)
318    {
319      svn_handle_error(err, stderr, FALSE);
320      svn_error_clear(err);
321      return(C_SCHEME_FALSE);
322    }
323
324  return(C_fix(revnum));
325EOF
326))
327
328(define svn-diff
329  (foreign-lambda* c-string* ((c-string path) (c-string user) (c-string pass))
330#<<EOF
331  apr_array_header_t *diff_opts = apr_array_make(svn_pool, 0, sizeof (char *));
332  char template[] = "/tmp/svnwiki-diff-XXXXXX";
333  svn_opt_revision_t rev1, rev2;
334  apr_file_t *outfile;
335  svn_error_t *err;
336
337  svnwiki_user = user;
338  svnwiki_pass = pass;
339
340  rev1.kind = svn_opt_revision_head;
341  rev2.kind = svn_opt_revision_working;
342
343  mkstemp(template);
344  apr_file_open(&outfile, template, APR_WRITE, APR_OS_DEFAULT, svn_pool);
345  err = svn_client_diff(diff_opts, path, &rev1, path, &rev2, TRUE, FALSE, TRUE, outfile, NULL, svn_ctx, svn_pool);
346  if (err)
347    {
348      svn_handle_error(err, stderr, FALSE);
349      svn_error_clear(err);
350      return(NULL);
351    }
352  apr_file_close(outfile);
353  return(strdup(template));
354EOF
355))
356
357(define svn-ls
358  (foreign-safe-lambda* scheme-object ((c-string path) (scheme-object result) (c-string user) (c-string pass))
359#<<EOF
360  apr_hash_t *dirents;
361  apr_hash_index_t *tmp;
362  svn_opt_revision_t head;
363  const char *can_path = svn_path_internal_style(path, svn_pool);
364
365  head.kind = svn_opt_revision_head;
366
367  svnwiki_user = user;
368  svnwiki_pass = pass;
369
370  err = svn_client_ls(&dirents, can_path, &head, FALSE, svn_ctx, svn_pool);
371  if (err)
372    {
373      svn_handle_error(err, stderr, FALSE);
374      svn_error_clear(err);
375      return(C_SCHEME_FALSE);
376    }
377
378  for (tmp = apr_hash_first(svn_pool, dirents); tmp; tmp = apr_hash_next(tmp))
379    {
380      const void *key;
381      apr_ssize_t keylen;
382      svn_dirent_t *value;
383
384      apr_hash_this(tmp, &key, &keylen, (void **) &value);
385      result = svn_ls_add(key,
386                          value->kind == svn_node_file ? C_fix(value->size) : C_SCHEME_FALSE,
387                          value->created_rev,
388                          result);
389    }
390
391  return(result);
392EOF
393))
394
395(define-external (svn_ls_add (c-string key) (scheme-object size) (long rev) (scheme-object result)) scheme-object
396  (cons (list key size rev) result))
397
398; Currently returns a list of all property values for a given file.
399
400(define svn-propget
401  (foreign-safe-lambda* scheme-object ((c-string propname) (c-string target) (c-string user) (c-string pass) (scheme-object result))
402#<<EOF
403  apr_hash_t *props;
404  apr_pool_t *pool;
405  svn_opt_revision_t head;
406  apr_hash_index_t *tmp;
407  svn_error_t *err;
408  void *resultroot;
409
410  head.kind = svn_opt_revision_unspecified;
411
412  svnwiki_user = user;
413  svnwiki_pass = pass;
414
415  pool = svn_pool_create(NULL);
416
417  resultroot = CHICKEN_new_gc_root();
418
419  CHICKEN_gc_root_set(resultroot, result);
420
421  err = svn_client_propget(&props, propname, target, &head, FALSE, svn_ctx, pool);
422  if (err)
423    {
424      apr_pool_destroy(pool);
425      svn_handle_error(err, stderr, FALSE);
426      svn_error_clear(err);
427      return(C_SCHEME_FALSE);
428    }
429
430  for (tmp = apr_hash_first(pool, props); tmp; tmp = apr_hash_next(tmp))
431    {
432      const void *key;
433      apr_ssize_t keylen;
434      svn_string_t *value;
435
436      apr_hash_this(tmp, &key, &keylen, (void **) &value);
437      CHICKEN_gc_root_set(resultroot, svn_propget_add(key, value->data, resultroot));
438    }
439
440  apr_pool_destroy(pool);
441
442  result = CHICKEN_gc_root_ref(resultroot);
443  CHICKEN_delete_gc_root(resultroot);
444
445  return(result);
446EOF
447))
448
449(define-external (svn_propget_add (c-string key) (c-string value) ((pointer void) result)) scheme-object
450  (cons (list key value) (gc-root-ref result)))
451
452(define svn-add
453  (foreign-safe-lambda* scheme-object ((c-string path))
454#<<EOF
455  svn_error_t *err;
456  err = svn_client_add(path, 0, svn_ctx, svn_pool);
457  if (err)
458    {
459      svn_handle_error(err, stderr, FALSE);
460      svn_error_clear(err);
461      return(C_SCHEME_FALSE);
462    }
463  return(C_SCHEME_TRUE);
464EOF
465))
466
467;;; History
468
469(define gc-root-ref
470  (foreign-lambda* void (((pointer "void") root)) "return(CHICKEN_gc_root_ref(root));"))
471
472(define-external (svn_history_add ((pointer void) root) (apr-hash-type changed-paths) (svn-revnum-type rev) (c-string author) (c-string date) (c-string message) (apr-pool-type pool)) svn-error-type
473  (let ((paths (changed-paths-fix changed-paths '())))
474    ((gc-root-ref root) paths rev author date message))
475  svn-no-error)
476
477(define-external (changed_paths_fix_one (c-string key) (svn-log-changed-path-type log-cp) ((pointer void) root)) scheme-object
478  (cons (cons key log-cp) (gc-root-ref root)))
479
480(define changed-paths-fix
481  (foreign-safe-lambda* scheme-object ((apr-hash-type paths) (scheme-object result)) #<<EOF
482  apr_pool_t *pool;
483  void *resultroot;
484  apr_hash_index_t *tmp;
485
486  if (!paths)
487    return(result);
488
489  resultroot = CHICKEN_new_gc_root();
490
491  CHICKEN_gc_root_set(resultroot, result);
492
493  pool = svn_pool_create(NULL);
494
495  for (tmp = apr_hash_first(pool, paths); tmp; tmp = apr_hash_next(tmp))
496    {
497      const void *key;
498      void *old;
499      apr_ssize_t keylen;
500      svn_log_changed_path_t *new = malloc(sizeof(svn_log_changed_path_t));
501
502      apr_hash_this(tmp, &key, &keylen, &old);
503
504      *new = * (svn_log_changed_path_t *) old;
505
506      if (new->copyfrom_path)
507        new->copyfrom_path = strdup(new->copyfrom_path);
508
509      CHICKEN_gc_root_set(resultroot, changed_paths_fix_one(key, new, resultroot));
510    }
511  apr_pool_destroy(pool);
512  result = CHICKEN_gc_root_ref(resultroot);
513  CHICKEN_delete_gc_root(resultroot);
514
515  return(result);
516EOF
517))
518
519(define svn-client-log2
520  (foreign-safe-lambda* bool ((c-string path) (svn-opt-revision-type start) (svn-opt-revision-type end) (int limit) (bool discover_changed_paths) (bool strict_node_history) (c-string user) (c-string pass) (scheme-object func))
521#<<EOF
522  apr_array_header_t *targets;
523  apr_pool_t *pool;
524  svn_error_t *err;
525  void *funcroot = CHICKEN_new_gc_root();
526
527  CHICKEN_gc_root_set(funcroot, func);
528
529  pool = svn_pool_create(NULL);
530
531  targets = apr_array_make(pool, 1, sizeof(char *));
532
533  *(char **)apr_array_push(targets) = path;
534
535  svnwiki_user = user;
536  svnwiki_pass = pass;
537
538  err = svn_client_log2(targets, start, end, limit, discover_changed_paths, strict_node_history, svn_history_add, (void *) funcroot, svn_ctx, pool);
539
540  apr_pool_destroy(pool);
541  CHICKEN_delete_gc_root(funcroot);
542
543  if (err)
544    {
545      svn_handle_error(err, stderr, FALSE);
546      svn_error_clear(err);
547      return(C_SCHEME_FALSE);
548    }
549
550  return(C_SCHEME_TRUE);
551EOF
552))
553
554; Currently returns a list with an entry for each commit between start and end.
555; Each entry is itself a list with the commit message, the number of the
556; revision that was created as the result of the commit, the author, the date
557; of the commit (a string) and the list of changed files.
558
559(define svn-client-log
560  (foreign-safe-lambda* bool ((c-string path) (svn-opt-revision-type start) (svn-opt-revision-type end) (bool discover_changed_paths) (bool strict_node_history) (c-string user) (c-string pass) (scheme-object func))
561#<<EOF
562  apr_array_header_t *targets;
563  apr_pool_t *pool;
564  svn_error_t *err;
565  void *funcroot = CHICKEN_new_gc_root();
566
567  CHICKEN_gc_root_set(funcroot, func);
568
569  pool = svn_pool_create(NULL);
570
571  targets = apr_array_make(pool, 1, sizeof(char *));
572
573  *(char **)apr_array_push(targets) = path;
574
575  svnwiki_user = user;
576  svnwiki_pass = pass;
577
578  err = svn_client_log(targets, start, end, discover_changed_paths, strict_node_history, svn_history_add, (void *) funcroot, svn_ctx, pool);
579
580  apr_pool_destroy(pool);
581  CHICKEN_delete_gc_root(funcroot);
582
583  if (err)
584    {
585      svn_handle_error(err, stderr, FALSE);
586      svn_error_clear(err);
587      return(C_SCHEME_FALSE);
588    }
589
590  return(C_SCHEME_TRUE);
591EOF
592))
593
594(define get-lock
595  (foreign-lambda* scheme-object ((c-string path))
596#<<EOF
597  int fd;
598  mkdir(path, S_IRWXU);
599  if ((fd = open(path, O_RDONLY)) == -1 || flock(fd, LOCK_EX) == -1)
600    {
601      fprintf(stderr, "%s: %s\n", path, strerror(errno));
602      exit(EXIT_FAILURE);
603    }
604  return C_SCHEME_TRUE;
605EOF
606))
607
608(define svn-time-from-cstring
609  (foreign-lambda* number ((c-string data))
610#<<EOF
611  apr_time_t when;
612  apr_pool_t *pool;
613  pool = svn_pool_create(NULL);
614  svn_time_from_cstring(&when, data, pool);
615  apr_pool_destroy(pool);
616  return((double) when);
617EOF
618))
619
620(define svn-client-revert
621  (foreign-safe-lambda* bool ((scheme-object paths) (bool recursive) (c-string user) (c-string pass))
622#<<EOF
623  apr_pool_t *pool;
624  apr_array_header_t *paths_array;
625  svn_error_t *err;
626  C_word tmp;
627  int len = 0;
628
629  pool = svn_pool_create(NULL);
630
631  for (tmp = paths; C_i_pairp(tmp) && tmp != C_SCHEME_END_OF_LIST; tmp = C_u_i_cdr(tmp))
632    len ++;
633
634  paths_array = apr_array_make(pool, len, sizeof(char *));
635
636  for (tmp = paths; C_i_pairp(tmp) && tmp != C_SCHEME_END_OF_LIST; tmp = C_u_i_cdr(tmp))
637    {
638      int len = C_header_size(C_u_i_car(tmp));
639      char *buffer = apr_palloc(svn_pool, len + 1);
640
641      strncpy(buffer, C_c_string(C_u_i_car(tmp)), len);
642      buffer[len] = 0;
643
644      (*((const char **) apr_array_push(paths_array))) = buffer;
645    }
646
647  err = svn_client_revert(paths_array, recursive, svn_ctx, pool);
648
649  apr_pool_destroy(pool);
650
651  if (err)
652    {
653      svn_handle_error(err, stderr, FALSE);
654      svn_error_clear(err);
655      return(C_SCHEME_FALSE);
656    }
657
658  return(C_SCHEME_TRUE);
659EOF
660))
661
662(define svn-client-resolved
663  (foreign-safe-lambda* bool ((c-string path) (bool recursive))
664#<<EOF
665  apr_pool_t *pool;
666  svn_error_t *err;
667
668  pool = svn_pool_create(NULL);
669
670  err = svn_client_resolved(path, recursive, svn_ctx, pool);
671
672  apr_pool_destroy(pool);
673
674  if (err)
675    {
676      svn_handle_error(err, stderr, FALSE);
677      svn_error_clear(err);
678      return(C_SCHEME_FALSE);
679    }
680
681  return(C_SCHEME_TRUE);
682 
683EOF
684))
685
686(define svn-path-canonicalize
687  (foreign-safe-lambda* c-string ((c-string old))
688#<<EOF
689  apr_pool_t *pool;
690  char *new;
691
692  pool = svn_pool_create(NULL);
693
694  new = strdup(svn_path_canonicalize(old, pool));
695
696  apr_pool_destroy(pool);
697
698  return(new);
699EOF
700))
701
702(define svn-client-cat
703  (foreign-safe-lambda* c-string* ((c-string path_or_url) (svn-opt-revision-type revision) (c-string user) (c-string pass))
704#<<EOF
705  apr_array_header_t *diff_opts = apr_array_make(svn_pool, 0, sizeof (char *));
706  char template[] = "/tmp/svnwiki-cat-XXXXXX";
707  apr_file_t *outfile;
708  svn_stream_t *out;
709  apr_pool_t *pool;
710
711  apr_file_t *stdout_file;
712  svn_error_t *err;
713
714  svnwiki_user = user;
715  svnwiki_pass = pass;
716
717  pool = svn_pool_create(NULL);
718
719  mkstemp(template);
720
721  apr_file_open(&outfile, template, APR_WRITE, APR_OS_DEFAULT, pool);
722  out = svn_stream_from_aprfile(outfile, pool);
723
724  err = svn_client_cat(out, path_or_url, revision, svn_ctx, pool);
725  if (err)
726    {
727      apr_pool_destroy(pool);
728      svn_handle_error(err, stderr, FALSE);
729      svn_error_clear(err);
730      return(NULL);
731    }
732
733  svn_stream_close(out);
734  apr_pool_destroy(pool);
735
736  return(strdup(template));
737EOF
738))
739
740(define svn-client-info
741  (foreign-safe-lambda* void ((c-string path_or_url) (svn-opt-revision-type peg_revision) (svn-opt-revision-type revision) (scheme-object receiver) (bool recurse) (c-string user) (c-string pass))
742#<<EOF
743  void *receiverroot;
744
745  apr_hash_t *props;
746  apr_pool_t *pool;
747  svn_opt_revision_t head;
748  apr_hash_index_t *tmp;
749  svn_error_t *err;
750
751  svnwiki_user = user;
752  svnwiki_pass = pass;
753
754  pool = svn_pool_create(NULL);
755
756  receiverroot = CHICKEN_new_gc_root();
757
758  CHICKEN_gc_root_set(receiverroot, receiver);
759
760  err = svn_client_info(path_or_url, peg_revision, revision, svn_client_info_receiver, receiverroot, recurse, svn_ctx, pool);
761  if (err)
762    {
763      apr_pool_destroy(pool);
764      svn_handle_error(err, stderr, FALSE);
765      svn_error_clear(err);
766      return(C_SCHEME_FALSE);
767    }
768
769  apr_pool_destroy(pool);
770
771  CHICKEN_delete_gc_root(receiverroot);
772
773  return(C_SCHEME_TRUE);
774EOF
775))
776
777(define-external (svn_client_info_receiver ((pointer void) baton) (c-string path) (svn-info-type info) (apr-pool-type pool)) svn-error-type
778  ((gc-root-ref baton) path info)
779  svn-no-error)
Note: See TracBrowser for help on using the repository browser.