summaryrefslogtreecommitdiff
path: root/perl/bio.xs
diff options
context:
space:
mode:
Diffstat (limited to 'perl/bio.xs')
-rw-r--r--perl/bio.xs448
1 files changed, 448 insertions, 0 deletions
diff --git a/perl/bio.xs b/perl/bio.xs
new file mode 100644
index 0000000000..3782d42062
--- /dev/null
+++ b/perl/bio.xs
@@ -0,0 +1,448 @@
+#include "p5SSLeay.h"
+
+static int p5_bio_ex_bio_ptr=0;
+static int p5_bio_ex_bio_callback=0;
+static int p5_bio_ex_bio_callback_data=0;
+
+static long p5_bio_callback(bio,state,parg,cmd,larg,ret)
+BIO *bio;
+int state;
+char *parg;
+int cmd;
+long larg;
+int ret;
+ {
+ int i;
+ SV *me,*cb;
+
+ me=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
+ cb=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_callback);
+ if (cb != NULL)
+ {
+ dSP;
+
+ ENTER ;
+ SAVETMPS;
+
+ PUSHMARK(sp);
+ XPUSHs(me);
+ XPUSHs(sv_2mortal(newSViv(state)));
+ XPUSHs(sv_2mortal(newSViv(cmd)));
+ if ((state == BIO_CB_READ) || (state == BIO_CB_WRITE))
+ {
+ XPUSHs(sv_2mortal(newSVpv(parg,larg)));
+ }
+ else
+ XPUSHs(&sv_undef);
+ /* ptr one */
+ XPUSHs(sv_2mortal(newSViv(larg)));
+ XPUSHs(sv_2mortal(newSViv(ret)));
+ PUTBACK;
+
+ i=perl_call_sv(cb,G_SCALAR);
+
+ SPAGAIN;
+ if (i == 1)
+ ret=POPi;
+ else
+ ret=1;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+ else
+ {
+ croak("Internal error in SSL p5_ssl_info_callback");
+ }
+ return(ret);
+ }
+
+int boot_bio()
+ {
+ p5_bio_ex_bio_ptr=
+ BIO_get_ex_new_index(0,"SSLeay::BIO",ex_new,NULL,ex_cleanup);
+ p5_bio_ex_bio_callback=
+ BIO_get_ex_new_index(0,"bio_callback",NULL,NULL,
+ ex_cleanup);
+ p5_bio_ex_bio_callback_data=
+ BIO_get_ex_new_index(0,"bio_callback_data",NULL,NULL,
+ ex_cleanup);
+ return(1);
+ }
+
+MODULE = SSLeay::BIO PACKAGE = SSLeay::BIO PREFIX = p5_BIO_
+
+VERSIONCHECK: DISABLE
+
+void
+p5_BIO_new_buffer_ssl_connect(...)
+ PREINIT:
+ SSL_CTX *ctx;
+ BIO *bio;
+ SV *arg;
+ PPCODE:
+ if (items == 1)
+ arg=ST(0);
+ else if (items == 2)
+ arg=ST(1);
+ else
+ arg=NULL;
+
+ if ((arg == NULL) || !(sv_derived_from(arg,"SSLeay::SSL::CTX")))
+ croak("Usage: SSLeay::BIO::new_buffer_ssl_connect(SSL_CTX)");
+ else
+ {
+ IV tmp=SvIV((SV *)SvRV(arg));
+ ctx=(SSL_CTX *)tmp;
+ }
+ EXTEND(sp,1);
+ bio=BIO_new_buffer_ssl_connect(ctx);
+ arg=new_ref("SSLeay::BIO",(char *)bio,0);
+ PUSHs(arg);
+ BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
+
+void
+p5_BIO_new_ssl_connect(...)
+ PREINIT:
+ SSL_CTX *ctx;
+ BIO *bio;
+ SV *arg;
+ PPCODE:
+ if (items == 1)
+ arg=ST(0);
+ else if (items == 2)
+ arg=ST(1);
+ else
+ arg=NULL;
+
+ if ((arg == NULL) || !(sv_derived_from(arg,"SSLeay::SSL::CTX")))
+ croak("Usage: SSLeay::BIO::new_ssl_connect(SSL_CTX)");
+ else
+ {
+ IV tmp=SvIV((SV *)SvRV(arg));
+ ctx=(SSL_CTX *)tmp;
+ }
+ EXTEND(sp,1);
+ bio=BIO_new_ssl_connect(ctx);
+ arg=new_ref("SSLeay::BIO",(char *)bio,0);
+ PUSHs(arg);
+ BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
+
+void
+p5_BIO_new(...)
+ PREINIT:
+ BIO *bio;
+ char *type;
+ SV *arg;
+ PPCODE:
+ pr_name("p5_BIO_new");
+ if ((items == 1) && SvPOK(ST(0)))
+ type=SvPV(ST(0),na);
+ else if ((items == 2) && SvPOK(ST(1)))
+ type=SvPV(ST(1),na);
+ else
+ croak("Usage: SSLeay::BIO::new(type)");
+
+ EXTEND(sp,1);
+ if (strcmp(type,"connect") == 0)
+ bio=BIO_new(BIO_s_connect());
+ else if (strcmp(type,"accept") == 0)
+ bio=BIO_new(BIO_s_accept());
+ else if (strcmp(type,"ssl") == 0)
+ bio=BIO_new(BIO_f_ssl());
+ else if (strcmp(type,"buffer") == 0)
+ bio=BIO_new(BIO_f_buffer());
+ else
+ croak("unknown BIO type");
+ arg=new_ref("SSLeay::BIO",(char *)bio,0);
+ PUSHs(arg);
+ BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
+
+int
+p5_BIO_hostname(bio,name)
+ BIO *bio;
+ char *name;
+ CODE:
+ RETVAL=BIO_set_hostname(bio,name);
+ OUTPUT:
+ RETVAL
+
+int
+p5_BIO_set_accept_port(bio,str)
+ BIO *bio;
+ char *str;
+ CODE:
+ RETVAL=BIO_set_accept_port(bio,str);
+ OUTPUT:
+ RETVAL
+
+int
+p5_BIO_do_handshake(bio)
+ BIO *bio;
+ CODE:
+ RETVAL=BIO_do_handshake(bio);
+ OUTPUT:
+ RETVAL
+
+BIO *
+p5_BIO_push(b,bio)
+ BIO *b;
+ BIO *bio;
+ CODE:
+ /* This reference will be reduced when the reference is
+ * let go, and then when the BIO_free_all() is called
+ * inside the SSLeay library by the BIO with this
+ * pushed into */
+ bio->references++;
+ RETVAL=BIO_push(b,bio);
+ OUTPUT:
+ RETVAL
+
+void
+p5_BIO_pop(b)
+ BIO *b
+ PREINIT:
+ BIO *bio;
+ char *type;
+ SV *arg;
+ PPCODE:
+ bio=BIO_pop(b);
+ if (bio != NULL)
+ {
+ /* This BIO will either be one created in the
+ * perl library, in which case it will have a perl
+ * SV, otherwise it will have been created internally,
+ * inside SSLeay. For the 'pushed in', it needs
+ * the reference count decememted. */
+ arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
+ if (arg == NULL)
+ {
+ arg=new_ref("SSLeay::BIO",(char *)bio,0);
+ PUSHs(arg);
+ BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
+ }
+ else
+ {
+ /* it was pushed in */
+ SvREFCNT_inc(arg);
+ PUSHs(arg);
+ if (bio->references < 1)
+ abort();
+ /* decrement the reference count */
+ BIO_free(bio);
+ }
+ }
+
+int
+p5_BIO_sysread(bio,in,num, ...)
+ BIO *bio;
+ SV *in;
+ int num;
+ PREINIT:
+ int i,n,olen;
+ int offset;
+ char *p;
+ CODE:
+ offset=0;
+ if (!SvPOK(in))
+ sv_setpvn(in,"",0);
+ SvPV(in,olen);
+ if (items > 3)
+ {
+ offset=SvIV(ST(3));
+ if (offset < 0)
+ {
+ if (-offset > olen)
+ croad("Offset outside string");
+ offset+=olen;
+ }
+ }
+ if ((num+offset) > olen)
+ {
+ SvGROW(in,num+offset+1);
+ p=SvPV(in,i);
+ memset(&(p[olen]),0,(num+offset)-olen+1);
+ }
+ p=SvPV(in,n);
+
+ i=BIO_read(bio,p+offset,num);
+ RETVAL=i;
+ if (i <= 0) i=0;
+ SvCUR_set(in,offset+i);
+ OUTPUT:
+ RETVAL
+
+int
+p5_BIO_syswrite(bio,in, ...)
+ BIO *bio;
+ SV *in;
+ PREINIT:
+ char *ptr;
+ int len,in_len;
+ int offset=0;
+ int n;
+ CODE:
+ ptr=SvPV(in,in_len);
+ if (items > 2)
+ {
+ len=SvOK(ST(2))?SvIV(ST(2)):in_len;
+ if (items > 3)
+ {
+ offset=SvIV(ST(3));
+ if (offset < 0)
+ {
+ if (-offset > in_len)
+ croak("Offset outside string");
+ offset+=in_len;
+ }
+ else if ((offset >= in_len) && (in_len > 0))
+ croak("Offset outside string");
+ }
+ if (len >= (in_len-offset))
+ len=in_len-offset;
+ }
+ else
+ len=in_len;
+
+ RETVAL=BIO_write(bio,ptr+offset,len);
+ OUTPUT:
+ RETVAL
+
+void
+p5_BIO_getline(bio)
+ BIO *bio;
+ PREINIT:
+ int i;
+ char *p;
+ PPCODE:
+ pr_name("p5_BIO_gets");
+ EXTEND(sp,1);
+ PUSHs(sv_newmortal());
+ sv_setpvn(ST(0),"",0);
+ SvGROW(ST(0),1024);
+ p=SvPV(ST(0),na);
+ i=BIO_gets(bio,p,1024);
+ if (i < 0) i=0;
+ SvCUR_set(ST(0),i);
+
+int
+p5_BIO_flush(bio)
+ BIO *bio;
+ CODE:
+ RETVAL=BIO_flush(bio);
+ OUTPUT:
+ RETVAL
+
+char *
+p5_BIO_type(bio)
+ BIO *bio;
+ CODE:
+ RETVAL=bio->method->name;
+ OUTPUT:
+ RETVAL
+
+void
+p5_BIO_next_bio(b)
+ BIO *b
+ PREINIT:
+ BIO *bio;
+ char *type;
+ SV *arg;
+ PPCODE:
+ bio=b->next_bio;
+ if (bio != NULL)
+ {
+ arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
+ if (arg == NULL)
+ {
+ arg=new_ref("SSLeay::BIO",(char *)bio,0);
+ PUSHs(arg);
+ BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
+ }
+ else
+ {
+ SvREFCNT_inc(arg);
+ PUSHs(arg);
+ }
+ }
+
+int
+p5_BIO_puts(bio,in)
+ BIO *bio;
+ SV *in;
+ PREINIT:
+ char *ptr;
+ CODE:
+ ptr=SvPV(in,na);
+ RETVAL=BIO_puts(bio,ptr);
+ OUTPUT:
+ RETVAL
+
+void
+p5_BIO_set_callback(bio,cb,...)
+ BIO *bio;
+ SV *cb;
+ PREINIT:
+ SV *arg=NULL;
+ SV *arg2=NULL;
+ CODE:
+ if (items > 3)
+ croak("Usage: SSLeay::BIO::set_callback(bio,callback[,arg]");
+ if (items == 3)
+ {
+ arg2=sv_mortalcopy(ST(2));
+ SvREFCNT_inc(arg2);
+ BIO_set_ex_data(bio,p5_bio_ex_bio_callback_data,
+ (char *)arg2);
+ }
+ arg=sv_mortalcopy(ST(1));
+ SvREFCNT_inc(arg);
+ BIO_set_ex_data(bio,p5_bio_ex_bio_callback,(char *)arg);
+ BIO_set_callback(bio,p5_bio_callback);
+
+void
+p5_BIO_DESTROY(bio)
+ BIO *bio
+ PREINIT:
+ SV *sv;
+ PPCODE:
+ pr_name_d("p5_BIO_DESTROY",bio->references);
+ printf("p5_BIO_DESTROY <%s> %d\n",bio->method->name,bio->references);
+ BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,NULL);
+ BIO_free_all(bio);
+
+int
+p5_BIO_set_ssl(bio,ssl)
+ BIO *bio;
+ SSL *ssl;
+ CODE:
+ pr_name("p5_BIO_set_ssl");
+ ssl->references++;
+ RETVAL=BIO_set_ssl(bio,ssl,BIO_CLOSE);
+ OUTPUT:
+ RETVAL
+
+int
+p5_BIO_number_read(bio)
+ BIO *bio;
+ CODE:
+ RETVAL=BIO_number_read(bio);
+ OUTPUT:
+ RETVAL
+
+int
+p5_BIO_number_written(bio)
+ BIO *bio;
+ CODE:
+ RETVAL=BIO_number_written(bio);
+ OUTPUT:
+ RETVAL
+
+int
+p5_BIO_references(bio)
+ BIO *bio;
+ CODE:
+ RETVAL=bio->references;
+ OUTPUT:
+ RETVAL
+