You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Ben Reser <be...@reser.org> on 2003/11/27 10:13:32 UTC
[PATCH] Implement prompt callback support for perl bindings
* subversion/bindings/swig/swigutil_pl.c
* subversion/bindings/swig/swigutil_pl.h
* subversion/bindings/swig/svn_client.i
* subversion/bindings/swig/perl/Core.pm
Implement support in the perl bindings for the prompt functions
(svn_client_get_simple_prompt_provider,
svn_client_get_username_prompt_provider,
svn_client_get_ssl_server_trust_prompt_provider,
svn_client_get_ssl_client_cert_prompt_provider,
svn_client_get_ssl_client_cert_pw_prompt_provider)
Index: subversion/bindings/swig/swigutil_pl.c
===================================================================
--- subversion/bindings/swig/swigutil_pl.c (revision 7861)
+++ subversion/bindings/swig/swigutil_pl.c (working copy)
@@ -817,6 +817,207 @@
return SVN_NO_ERROR;
}
+svn_error_t *svn_swig_pl_thunk_simple_prompt(svn_auth_cred_simple_t **cred,
+ void *baton,
+ const char *realm,
+ const char *username,
+ apr_pool_t *pool)
+{
+ SV *prompt_func, *result;
+ swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *");
+ swig_type_info *credinfo = SWIG_TypeQuery("svn_auth_cred_simple_t *");
+
+ /* baton here contains the pointer to the CV
+ * Before we can use it we need to convert it back to an SV and
+ * place it back in a refernce. We have to do this because the
+ * reference we would be passed at runtime could be reaped by garbage
+ * collection before we make the callback */
+ prompt_func = newRV_inc(INT2PTR(SV *,baton));
+ if (!SvROK(prompt_func) && SvTYPE(SvRV(prompt_func)) != SVt_PVCV)
+ return SVN_NO_ERROR;
+
+ /* Be nice and allocate the memory for the cred structure before passing it
+ * off to the perl space */
+ *cred = apr_pcalloc(pool, sizeof(**cred));
+ if (!*cred) {
+ croak("Could not allocate memory for cred structure");
+ }
+
+ perl_callback_thunk (CALL_SV,
+ prompt_func, &result,
+ "SssS", *cred, credinfo,
+ realm, username, pool, poolinfo);
+
+ /* Must clean up our reference we make or we'll leak */
+ SvREFCNT_dec(prompt_func);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_swig_pl_thunk_username_prompt(svn_auth_cred_username_t **cred,
+ void *baton,
+ const char *realm,
+ apr_pool_t *pool)
+{
+ SV *prompt_func, *result;
+ swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *");
+ swig_type_info *credinfo = SWIG_TypeQuery("svn_auth_cred_username_t *");
+
+ /* baton here contains the pointer to the CV
+ * Before we can use it we need to convert it back to an SV and
+ * place it back in a refernce. We have to do this because the
+ * reference we would be passed at runtime could be reaped by garbage
+ * collection before we make the callback */
+ prompt_func = newRV_inc(INT2PTR(SV *,baton));
+ if (!SvROK(prompt_func) && SvTYPE(SvRV(prompt_func)) != SVt_PVCV)
+ return SVN_NO_ERROR;
+
+ /* Be nice and allocate the memory for the cred structure before passing it
+ * off to the perl space */
+ *cred = apr_pcalloc(pool, sizeof(**cred));
+ if (!*cred) {
+ croak("Could not allocate memory for cred structure");
+ }
+
+ perl_callback_thunk (CALL_SV,
+ prompt_func, &result,
+ "SsS", *cred, credinfo,
+ realm, pool, poolinfo);
+
+ /* Must clean up our reference we make or we'll leak */
+ SvREFCNT_dec(prompt_func);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_swig_pl_thunk_ssl_server_trust_prompt(
+ svn_auth_cred_ssl_server_trust_t **cred,
+ void *baton,
+ const char *realm,
+ int failures,
+ const svn_auth_ssl_server_cert_info_t *cert_info,
+ apr_pool_t *pool)
+{
+ SV *prompt_func, *result;
+ swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *");
+ swig_type_info *credinfo = SWIG_TypeQuery(
+ "svn_auth_cred_ssl_server_trust_t *");
+ swig_type_info *cert_info_info = SWIG_TypeQuery(
+ "svn_auth_ssl_server_cert_info_t *");
+
+ /* baton here contains the pointer to the CV
+ * Before we can use it we need to convert it back to an SV and
+ * place it back in a refernce. We have to do this because the
+ * reference we would be passed at runtime could be reaped by garbage
+ * collection before we make the callback */
+ prompt_func = newRV_inc(INT2PTR(SV *,baton));
+ if (!SvROK(prompt_func) && SvTYPE(SvRV(prompt_func)) != SVt_PVCV)
+ return SVN_NO_ERROR;
+
+ /* Be nice and allocate the memory for the cred structure before passing it
+ * off to the perl space */
+ *cred = apr_pcalloc(pool, sizeof(**cred));
+ if (!*cred) {
+ croak("Could not allocate memory for cred structure");
+ }
+
+ perl_callback_thunk (CALL_SV,
+ prompt_func, &result,
+ "SsiSS", *cred, credinfo,
+ realm, failures,
+ cert_info, cert_info_info,
+ pool, poolinfo);
+
+ /* Must clean up our reference we make or we'll leak */
+ SvREFCNT_dec(prompt_func);
+
+ /* Allow the perl callback to indicate failure by setting all vars to 0
+ * or by simply doing nothing. While still allowing them to indicate
+ * failure by setting the cred strucutre's pointer to 0 via $$cred = 0 */
+ if (*cred) {
+ if ((*cred)->trust_permanently == 0 &&
+ (*cred)->accepted_failures == 0) {
+ *cred = NULL;
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_swig_pl_thunk_ssl_client_cert_prompt(
+ svn_auth_cred_ssl_client_cert_t **cred,
+ void *baton,
+ apr_pool_t *pool)
+{
+ SV *prompt_func, *result;
+ swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *");
+ swig_type_info *credinfo = SWIG_TypeQuery(
+ "svn_auth_cred_ssl_client_cert_t *");
+
+ /* baton here contains the pointer to the CV
+ * Before we can use it we need to convert it back to an SV and
+ * place it back in a refernce. We have to do this because the
+ * reference we would be passed at runtime could be reaped by garbage
+ * collection before we make the callback */
+ prompt_func = newRV_inc(INT2PTR(SV *,baton));
+ if (!SvROK(prompt_func) && SvTYPE(SvRV(prompt_func)) != SVt_PVCV)
+ return SVN_NO_ERROR;
+
+ /* Be nice and allocate the memory for the cred structure before passing it
+ * off to the perl space */
+ *cred = apr_pcalloc(pool, sizeof(**cred));
+ if (!*cred) {
+ croak("Could not allocate memory for cred structure");
+ }
+
+ perl_callback_thunk (CALL_SV,
+ prompt_func, &result,
+ "SS", *cred, credinfo,
+ pool, poolinfo);
+
+ /* Must clean up our reference we make or we'll leak */
+ SvREFCNT_dec(prompt_func);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_swig_pl_thunk_ssl_client_cert_pw_prompt(
+ svn_auth_cred_ssl_client_cert_pw_t **cred,
+ void *baton,
+ apr_pool_t *pool)
+{
+ SV *prompt_func, *result;
+ swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *");
+ swig_type_info *credinfo = SWIG_TypeQuery(
+ "svn_auth_cred_ssl_client_cert_pw_t *");
+
+ /* baton here contains the pointer to the CV
+ * Before we can use it we need to convert it back to an SV and
+ * place it back in a refernce. We have to do this because the
+ * reference we would be passed at runtime could be reaped by garbage
+ * collection before we make the callback */
+ prompt_func = newRV_inc(INT2PTR(SV *,baton));
+ if (!SvROK(prompt_func) && SvTYPE(SvRV(prompt_func)) != SVt_PVCV)
+ return SVN_NO_ERROR;
+
+ /* Be nice and allocate the memory for the cred structure before passing it
+ * off to the perl space */
+ *cred = apr_pcalloc(pool, sizeof(**cred));
+ if (!*cred) {
+ croak("Could not allocate memory for cred structure");
+ }
+
+ perl_callback_thunk (CALL_SV,
+ prompt_func, &result,
+ "SS", *cred, credinfo,
+ pool, poolinfo);
+
+ /* Must clean up our reference we make or we'll leak */
+ SvREFCNT_dec(prompt_func);
+
+ return SVN_NO_ERROR;
+}
+
/* default pool support */
apr_pool_t *current_pool;
Index: subversion/bindings/swig/swigutil_pl.h
===================================================================
--- subversion/bindings/swig/swigutil_pl.h (revision 7861)
+++ subversion/bindings/swig/swigutil_pl.h (working copy)
@@ -112,7 +112,40 @@
SV *perl_callbacks,
apr_pool_t *pool);
+/* thunked simple_prompt callback function */
+svn_error_t *svn_swig_pl_thunk_simple_prompt (svn_auth_cred_simple_t **cred,
+ void *baton,
+ const char *realm,
+ const char *username,
+ apr_pool_t *pool);
+/* thunked username_prompt callback function */
+svn_error_t *svn_swig_pl_thunk_username_prompt (svn_auth_cred_username_t **cred,
+ void *baton,
+ const char *realm,
+ apr_pool_t *pool);
+
+/* thunked ssl_server_trust_prompt callback function */
+svn_error_t *svn_swig_pl_thunk_ssl_server_trust_prompt(
+ svn_auth_cred_ssl_server_trust_t **cred,
+ void *baton,
+ const char *realm,
+ int failures,
+ const svn_auth_ssl_server_cert_info_t *cert_info,
+ apr_pool_t *pool);
+
+/* thunked ssl_client_cert callback function */
+svn_error_t *svn_swig_pl_thunk_ssl_client_cert_prompt (
+ svn_auth_cred_ssl_client_cert_t **cred,
+ void *baton,
+ apr_pool_t *pool);
+
+/* thunked ssl_client_cert_pw callback function */
+svn_error_t *svn_swig_pl_thunk_ssl_client_cert_pw_prompt (
+ svn_auth_cred_ssl_client_cert_pw_t **cred,
+ void *baton,
+ apr_pool_t *pool);
+
/* svn_stream_t helpers */
svn_error_t *svn_swig_pl_make_stream (svn_stream_t **stream, SV *obj);
SV *svn_swig_pl_from_stream (svn_stream_t *stream);
Index: subversion/bindings/swig/svn_client.i
===================================================================
--- subversion/bindings/swig/svn_client.i (revision 7861)
+++ subversion/bindings/swig/svn_client.i (working copy)
@@ -248,6 +248,144 @@
any API, but svn_client_ls returns a hash of pointers to dirents. */
%types(svn_dirent_t *);
+/* -----------------------------------------------------------------------
+ thunk the various authentication prompt functions
+*/
+%typemap(perl5, in) (svn_auth_simple_prompt_func_t prompt_func,
+ void *prompt_baton) {
+ $1 = svn_swig_pl_thunk_simple_prompt;
+
+ /* Because the callback occurs long after the function we're wrapping
+ it is likely that the rv or sv we are passed will be reaped by
+ perl before the callback happens. So we must get the cv for the
+ callback sub and store it in the baton */
+ if (SvROK((SV *)$input) && SvTYPE(SvRV((SV *)$input)) == SVt_PVCV) {
+ /* If the input is a coderef get the pointer to the cv it references
+ and store it in the baton*/
+ $2 = (void *)PTR2UV(SvRV($input));
+ } else if (SvPOK($input)) {
+ /* If the input is a string try to look up the cv by name and store
+ the pointer to it in the baton*/
+ char *cv_name = SvPV_nolen($input);
+ CV *cv = get_cv(cv_name,FALSE);
+ if (cv && SvTYPE((SV *)cv) == SVt_PVCV) {
+ $2 = (void *)PTR2UV(cv);
+ } else {
+ croak("No sub by that name");
+ }
+ } else {
+ croak("Not a CODE reference");
+ }
+}
+
+%typemap(perl5, in) (svn_auth_username_prompt_func_t prompt_func,
+ void *prompt_baton) {
+ $1 = svn_swig_pl_thunk_username_prompt;
+
+ /* Because the callback occurs long after the function we're wrapping
+ it is likely that the rv or sv we are passed will be reaped by
+ perl before the callback happens. So we must get the cv for the
+ callback sub and store it in the baton */
+ if (SvROK((SV *)$input) && SvTYPE(SvRV((SV *)$input)) == SVt_PVCV) {
+ /* If the input is a coderef get the pointer to the cv it references
+ and store it in the baton*/
+ $2 = (void *)PTR2UV(SvRV($input));
+ } else if (SvPOK($input)) {
+ /* If the input is a string try to look up the cv by name and store
+ the pointer to it in the baton*/
+ char *cv_name = SvPV_nolen($input);
+ CV *cv = get_cv(cv_name,FALSE);
+ if (cv && SvTYPE((SV *)cv) == SVt_PVCV) {
+ $2 = (void *)PTR2UV(cv);
+ } else {
+ croak("No sub by that name");
+ }
+ } else {
+ croak("Not a CODE reference");
+ }
+}
+
+%typemap(perl5, in) (svn_auth_ssl_server_trust_prompt_func_t prompt_func,
+ void *prompt_baton) {
+ $1 = svn_swig_pl_thunk_ssl_server_trust_prompt;
+
+ /* Because the callback occurs long after the function we're wrapping
+ it is likely that the rv or sv we are passed will be reaped by
+ perl before the callback happens. So we must get the cv for the
+ callback sub and store it in the baton */
+ if (SvROK((SV *)$input) && SvTYPE(SvRV((SV *)$input)) == SVt_PVCV) {
+ /* If the input is a coderef get the pointer to the cv it references
+ and store it in the baton*/
+ $2 = (void *)PTR2UV(SvRV($input));
+ } else if (SvPOK($input)) {
+ /* If the input is a string try to look up the cv by name and store
+ the pointer to it in the baton*/
+ char *cv_name = SvPV_nolen($input);
+ CV *cv = get_cv(cv_name,FALSE);
+ if (cv && SvTYPE((SV *)cv) == SVt_PVCV) {
+ $2 = (void *)PTR2UV(cv);
+ } else {
+ croak("No sub by that name");
+ }
+ } else {
+ croak("Not a CODE reference");
+ }
+}
+
+%typemap(perl5, in) (svn_auth_ssl_client_cert_prompt_func_t prompt_func,
+ void *prompt_baton) {
+ $1 = svn_swig_pl_thunk_ssl_client_cert_prompt;
+
+ /* Because the callback occurs long after the function we're wrapping
+ it is likely that the rv or sv we are passed will be reaped by
+ perl before the callback happens. So we must get the cv for the
+ callback sub and store it in the baton */
+ if (SvROK((SV *)$input) && SvTYPE(SvRV((SV *)$input)) == SVt_PVCV) {
+ /* If the input is a coderef get the pointer to the cv it references
+ and store it in the baton*/
+ $2 = (void *)PTR2UV(SvRV($input));
+ } else if (SvPOK($input)) {
+ /* If the input is a string try to look up the cv by name and store
+ the pointer to it in the baton*/
+ char *cv_name = SvPV_nolen($input);
+ CV *cv = get_cv(cv_name,FALSE);
+ if (cv && SvTYPE((SV *)cv) == SVt_PVCV) {
+ $2 = (void *)PTR2UV(cv);
+ } else {
+ croak("No sub by that name");
+ }
+ } else {
+ croak("Not a CODE reference");
+ }
+}
+
+%typemap(perl5, in) (svn_auth_ssl_client_cert_pw_prompt_func_t prompt_func,
+ void *prompt_baton) {
+ $1 = svn_swig_pl_thunk_ssl_client_cert_pw_prompt;
+
+ /* Because the callback occurs long after the function we're wrapping
+ it is likely that the rv or sv we are passed will be reaped by
+ perl before the callback happens. So we must get the cv for the
+ callback sub and store it in the baton */
+ if (SvROK((SV *)$input) && SvTYPE(SvRV((SV *)$input)) == SVt_PVCV) {
+ /* If the input is a coderef get the pointer to the cv it references
+ and store it in the baton*/
+ $2 = (void *)PTR2UV(SvRV($input));
+ } else if (SvPOK($input)) {
+ /* If the input is a string try to look up the cv by name and store
+ the pointer to it in the baton*/
+ char *cv_name = SvPV_nolen($input);
+ CV *cv = get_cv(cv_name,FALSE);
+ if (cv && SvTYPE((SV *)cv) == SVt_PVCV) {
+ $2 = (void *)PTR2UV(cv);
+ } else {
+ croak("No sub by that name");
+ }
+ } else {
+ croak("Not a CODE reference");
+ }
+}
+
/* ----------------------------------------------------------------------- */
Index: subversion/bindings/swig/perl/Core.pm
===================================================================
--- subversion/bindings/swig/perl/Core.pm (revision 7861)
+++ subversion/bindings/swig/perl/Core.pm (working copy)
@@ -342,10 +346,54 @@
=cut
+package _p_svn_auth_cred_simple_t;
+use SVN::Base qw(Core svn_auth_cred_simple_t_);
+
+=head2 svn_auth_cred_simple_t
+
+=cut
+
+package _p_svn_auth_cred_username_t;
+use SVN::Base qw(Core svn_auth_cred_username_t_);
+
+=head2 svn_auth_cred_username_t
+
+=cut
+
+package _p_svn_auth_cred_ssl_server_trust_t;
+use SVN::Base qw(Core svn_auth_cred_ssl_server_trust_t_);
+
+=head2 svn_auth_cred_ssl_server_trust_t
+
+=cut
+
+package _p_svn_auth_ssl_server_cert_info_t;
+use SVN::Base qw(Core svn_auth_ssl_server_cert_info_t_);
+
+=head2 svn_auth_ssl_server_cert_info_t
+
+=cut
+
+package _p_svn_auth_cred_ssl_client_cert_t;
+use SVN::Base qw(Core svn_auth_cred_ssl_client_cert_t_);
+
+=head2 svn_auth_cred_ssl_client_cert_t
+
+=cut
+
+package _p_svn_auth_cred_ssl_client_cert_pw_t;
+use SVN::Base qw(Core svn_auth_cred_ssl_client_cert_pw_t_);
+
+=head2 svn_auth_cred_ssl_client_cert_pw_t
+
+=cut
+
=head1 AUTHORS
Chia-liang Kao E<lt>clkao@clkao.orgE<gt>
+Ben Reser E<lt>ben@reser.orgE<gt>
+
=head1 COPYRIGHT
Copyright (c) 2003 CollabNet. All rights reserved.
--
Ben Reser <be...@reser.org>
http://ben.reser.org
"Conscience is the inner voice which warns us somebody may be looking."
- H.L. Mencken
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Re: [PATCH] Implement prompt callback support for perl bindings
Posted by Ben Reser <be...@reser.org>.
New version of this patch.
* subversion/bindings/swig/swigutil_pl.c
* subversion/bindings/swig/swigutil_pl.h
(svn_swig_pl_get_sv_from_cv,
svn_swig_pl_get_cv_from_sv): New functions
to handle converting to and from SV and CV
types.
(perl_callback_thunk): Add a CALL_CV type
that accepts a CV and converts it for you.
* subversion/bindings/swig/swigutil_pl.c
* subversion/bindings/swig/swigutil_pl.h
* subversion/bindings/swig/svn_client.i
Implement support for the prompt functions
in the perl bindings
(svn_client_get_simple_prompt_provider,
svn_client_get_username_prompt_provider,
svn_client_get_ssl_server_trust_prompt_provider,
svn_client_get_ssl_client_cert_prompt_provider,
svn_client_get_ssl_client_cert_pw_prompt_provider)
* subversion/bindings/swig/perl/Core.pm
Packages for easy use of the credential types
passed to the prompt callbacks.
* subversion/bindings/swig/perl/Client.pm
Add documentation for the use of
svn_client_get_simple_prompt_provider.
patch attached due to probably wrapping.
--
Ben Reser <be...@reser.org>
http://ben.reser.org
"Conscience is the inner voice which warns us somebody may be looking."
- H.L. Mencken
Re: [PATCH] Implement prompt callback support for perl bindings
Posted by Ben Reser <be...@reser.org>.
On Thu, Nov 27, 2003 at 02:13:32AM -0800, Ben Reser wrote:
> * subversion/bindings/swig/swigutil_pl.c
> * subversion/bindings/swig/swigutil_pl.h
> * subversion/bindings/swig/svn_client.i
> * subversion/bindings/swig/perl/Core.pm
> Implement support in the perl bindings for the prompt functions
> (svn_client_get_simple_prompt_provider,
> svn_client_get_username_prompt_provider,
> svn_client_get_ssl_server_trust_prompt_provider,
> svn_client_get_ssl_client_cert_prompt_provider,
> svn_client_get_ssl_client_cert_pw_prompt_provider)
Blah looks like it wrapped. Attachment coming.
Forgot to mention in the previous changelog that this adds my name to
the AUTHORS section of Core.pm, so this should be added to the
changelog:
Add my name to AUTHORS section of Core.pm
--
Ben Reser <be...@reser.org>
http://ben.reser.org
"Conscience is the inner voice which warns us somebody may be looking."
- H.L. Mencken