This commit was generated by cvs2svn to track changes on a CVS vendor
[openssl.git] / perl / openssl_bio.xs
1 #include "p5SSLeay.h"
2
3 static int p5_bio_ex_bio_ptr=0;
4 static int p5_bio_ex_bio_callback=0;
5 static int p5_bio_ex_bio_callback_data=0;
6
7 static long p5_bio_callback(bio,state,parg,cmd,larg,ret)
8 BIO *bio;
9 int state;
10 char *parg;
11 int cmd;
12 long larg;
13 int ret;
14         {
15         int i;
16         SV *me,*cb;
17
18         me=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
19         cb=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_callback);
20         if (cb != NULL)
21                 {
22                 dSP;
23
24                 ENTER ;
25                 SAVETMPS;
26
27                 PUSHMARK(sp);
28                 XPUSHs(me);
29                 XPUSHs(sv_2mortal(newSViv(state)));
30                 XPUSHs(sv_2mortal(newSViv(cmd)));
31                 if ((state == BIO_CB_READ) || (state == BIO_CB_WRITE))
32                         {
33                         XPUSHs(sv_2mortal(newSVpv(parg,larg)));
34                         }
35                 else
36                         XPUSHs(&sv_undef);
37                 /* ptr one */
38                 XPUSHs(sv_2mortal(newSViv(larg)));
39                 XPUSHs(sv_2mortal(newSViv(ret)));
40                 PUTBACK;
41
42                 i=perl_call_sv(cb,G_SCALAR);
43
44                 SPAGAIN;
45                 if (i == 1)
46                         ret=POPi;
47                 else
48                         ret=1;
49                 PUTBACK;
50                 FREETMPS;
51                 LEAVE;
52                 }
53         else
54                 {
55                 croak("Internal error in SSL p5_ssl_info_callback");
56                 }
57         return(ret);
58         }
59
60 int boot_bio()
61         {
62         p5_bio_ex_bio_ptr=
63                 BIO_get_ex_new_index(0,"SSLeay::BIO",ex_new,NULL,ex_cleanup);
64         p5_bio_ex_bio_callback= 
65                 BIO_get_ex_new_index(0,"bio_callback",NULL,NULL,
66                         ex_cleanup);
67         p5_bio_ex_bio_callback_data=
68                 BIO_get_ex_new_index(0,"bio_callback_data",NULL,NULL,
69                         ex_cleanup);
70         return(1);
71         }
72
73 MODULE =  SSLeay::BIO   PACKAGE = SSLeay::BIO PREFIX = p5_BIO_
74
75 VERSIONCHECK: DISABLE
76
77 void
78 p5_BIO_new_buffer_ssl_connect(...)
79         PREINIT:
80                 SSL_CTX *ctx;
81                 BIO *bio;
82                 SV *arg;
83         PPCODE:
84                 if (items == 1)
85                         arg=ST(0);
86                 else if (items == 2)
87                         arg=ST(1);
88                 else
89                         arg=NULL;
90
91                 if ((arg == NULL) || !(sv_derived_from(arg,"SSLeay::SSL::CTX")))
92                         croak("Usage: SSLeay::BIO::new_buffer_ssl_connect(SSL_CTX)");
93                 else
94                         {
95                         IV tmp=SvIV((SV *)SvRV(arg));
96                         ctx=(SSL_CTX *)tmp;
97                         }
98                 EXTEND(sp,1);
99                 bio=BIO_new_buffer_ssl_connect(ctx);
100                 arg=new_ref("SSLeay::BIO",(char *)bio,0);
101                 PUSHs(arg);
102                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
103
104 void
105 p5_BIO_new_ssl_connect(...)
106         PREINIT:
107                 SSL_CTX *ctx;
108                 BIO *bio;
109                 SV *arg;
110         PPCODE:
111                 if (items == 1)
112                         arg=ST(0);
113                 else if (items == 2)
114                         arg=ST(1);
115                 else
116                         arg=NULL;
117
118                 if ((arg == NULL) || !(sv_derived_from(arg,"SSLeay::SSL::CTX")))
119                         croak("Usage: SSLeay::BIO::new_ssl_connect(SSL_CTX)");
120                 else
121                         {
122                         IV tmp=SvIV((SV *)SvRV(arg));
123                         ctx=(SSL_CTX *)tmp;
124                         }
125                 EXTEND(sp,1);
126                 bio=BIO_new_ssl_connect(ctx);
127                 arg=new_ref("SSLeay::BIO",(char *)bio,0);
128                 PUSHs(arg);
129                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
130
131 void
132 p5_BIO_new(...)
133         PREINIT:
134                 BIO *bio;
135                 char *type;
136                 SV *arg;
137         PPCODE:
138                 pr_name("p5_BIO_new");
139                 if ((items == 1) && SvPOK(ST(0)))
140                         type=SvPV(ST(0),na);
141                 else if ((items == 2) && SvPOK(ST(1)))
142                         type=SvPV(ST(1),na);
143                 else
144                         croak("Usage: SSLeay::BIO::new(type)");
145
146                 EXTEND(sp,1);
147                 if (strcmp(type,"connect") == 0)
148                         bio=BIO_new(BIO_s_connect());
149                 else if (strcmp(type,"accept") == 0)
150                         bio=BIO_new(BIO_s_accept());
151                 else if (strcmp(type,"ssl") == 0)
152                         bio=BIO_new(BIO_f_ssl());
153                 else if (strcmp(type,"buffer") == 0)
154                         bio=BIO_new(BIO_f_buffer());
155                 else
156                         croak("unknown BIO type");
157                 arg=new_ref("SSLeay::BIO",(char *)bio,0);
158                 PUSHs(arg);
159                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
160
161 int
162 p5_BIO_hostname(bio,name)
163         BIO *bio;
164         char *name;
165         CODE:
166                 RETVAL=BIO_set_hostname(bio,name);
167         OUTPUT:
168                 RETVAL
169
170 int
171 p5_BIO_set_accept_port(bio,str)
172         BIO *bio;
173         char *str;
174         CODE:
175                 RETVAL=BIO_set_accept_port(bio,str);
176         OUTPUT:
177                 RETVAL
178
179 int
180 p5_BIO_do_handshake(bio)
181         BIO *bio;
182         CODE:
183                 RETVAL=BIO_do_handshake(bio);
184         OUTPUT:
185                 RETVAL
186
187 BIO *
188 p5_BIO_push(b,bio)
189         BIO *b;
190         BIO *bio;
191         CODE:
192                 /* This reference will be reduced when the reference is
193                  * let go, and then when the BIO_free_all() is called
194                  * inside the SSLeay library by the BIO with this
195                  * pushed into */
196                 bio->references++;
197                 RETVAL=BIO_push(b,bio);
198         OUTPUT:
199                 RETVAL
200
201 void
202 p5_BIO_pop(b)
203         BIO *b
204         PREINIT:
205                 BIO *bio;
206                 char *type;
207                 SV *arg;
208         PPCODE:
209                 bio=BIO_pop(b);
210                 if (bio != NULL)
211                         {
212                         /* This BIO will either be one created in the
213                          * perl library, in which case it will have a perl
214                          * SV, otherwise it will have been created internally,
215                          * inside SSLeay.  For the 'pushed in', it needs
216                          * the reference count decememted. */
217                         arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
218                         if (arg == NULL)
219                                 {
220                                 arg=new_ref("SSLeay::BIO",(char *)bio,0);
221                                 PUSHs(arg);
222                                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
223                                 }
224                         else
225                                 {
226                                 /* it was pushed in */
227                                 SvREFCNT_inc(arg);
228                                 PUSHs(arg);
229                                 if (bio->references < 1)
230                                         abort();
231                                 /* decrement the reference count */
232                                 BIO_free(bio);
233                                 }
234                         }
235
236 int
237 p5_BIO_sysread(bio,in,num, ...)
238         BIO *bio;
239         SV *in;
240         int num;
241         PREINIT:
242                 int i,n,olen;
243                 int offset;
244                 char *p;
245         CODE:
246                 offset=0;
247                 if (!SvPOK(in))
248                         sv_setpvn(in,"",0);
249                 SvPV(in,olen);
250                 if (items > 3)
251                         {
252                         offset=SvIV(ST(3));
253                         if (offset < 0)
254                                 {
255                                 if (-offset > olen)
256                                         croad("Offset outside string");
257                                 offset+=olen;
258                                 }
259                         }
260                 if ((num+offset) > olen)
261                         {
262                         SvGROW(in,num+offset+1);
263                         p=SvPV(in,i);
264                         memset(&(p[olen]),0,(num+offset)-olen+1);
265                         }
266                 p=SvPV(in,n);
267
268                 i=BIO_read(bio,p+offset,num);
269                 RETVAL=i;
270                 if (i <= 0) i=0;
271                 SvCUR_set(in,offset+i);
272         OUTPUT:
273                 RETVAL
274
275 int
276 p5_BIO_syswrite(bio,in, ...)
277         BIO *bio;
278         SV *in;
279         PREINIT:
280                 char *ptr;
281                 int len,in_len;
282                 int offset=0;
283                 int n;
284         CODE:
285                 ptr=SvPV(in,in_len);
286                 if (items > 2)
287                         {
288                         len=SvOK(ST(2))?SvIV(ST(2)):in_len;
289                         if (items > 3)
290                                 {
291                                 offset=SvIV(ST(3));
292                                 if (offset < 0)
293                                         {
294                                         if (-offset > in_len)
295                                                 croak("Offset outside string");
296                                         offset+=in_len;
297                                         }
298                                 else if ((offset >= in_len) && (in_len > 0))
299                                         croak("Offset outside string");
300                                 }
301                         if (len >= (in_len-offset))
302                                 len=in_len-offset;
303                         }
304                 else
305                         len=in_len;
306
307                 RETVAL=BIO_write(bio,ptr+offset,len);
308         OUTPUT:
309                 RETVAL
310
311 void
312 p5_BIO_getline(bio)
313         BIO *bio;
314         PREINIT:
315                 int i;
316                 char *p;
317         PPCODE:
318                 pr_name("p5_BIO_gets");
319                 EXTEND(sp,1);
320                 PUSHs(sv_newmortal());
321                 sv_setpvn(ST(0),"",0);
322                 SvGROW(ST(0),1024);
323                 p=SvPV(ST(0),na);
324                 i=BIO_gets(bio,p,1024);
325                 if (i < 0) i=0;
326                 SvCUR_set(ST(0),i);
327
328 int
329 p5_BIO_flush(bio)
330         BIO *bio;
331         CODE:
332                 RETVAL=BIO_flush(bio);
333         OUTPUT:
334                 RETVAL
335
336 char *
337 p5_BIO_type(bio)
338         BIO *bio;
339         CODE:
340                 RETVAL=bio->method->name;
341         OUTPUT:
342                 RETVAL
343
344 void
345 p5_BIO_next_bio(b)
346         BIO *b
347         PREINIT:
348                 BIO *bio;
349                 char *type;
350                 SV *arg;
351         PPCODE:
352                 bio=b->next_bio;
353                 if (bio != NULL)
354                         {
355                         arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
356                         if (arg == NULL)
357                                 {
358                                 arg=new_ref("SSLeay::BIO",(char *)bio,0);
359                                 PUSHs(arg);
360                                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
361                                 }
362                         else
363                                 {
364                                 SvREFCNT_inc(arg);
365                                 PUSHs(arg);
366                                 }
367                         }
368
369 int
370 p5_BIO_puts(bio,in)
371         BIO *bio;
372         SV *in;
373         PREINIT:
374                 char *ptr;
375         CODE:
376                 ptr=SvPV(in,na);
377                 RETVAL=BIO_puts(bio,ptr);
378         OUTPUT:
379                 RETVAL
380
381 void
382 p5_BIO_set_callback(bio,cb,...)
383         BIO *bio;
384         SV *cb;
385         PREINIT:
386                 SV *arg=NULL;
387                 SV *arg2=NULL;
388         CODE:
389                 if (items > 3)
390                         croak("Usage: SSLeay::BIO::set_callback(bio,callback[,arg]");
391                 if (items == 3)
392                         {
393                         arg2=sv_mortalcopy(ST(2));
394                         SvREFCNT_inc(arg2);
395                         BIO_set_ex_data(bio,p5_bio_ex_bio_callback_data,
396                                 (char *)arg2);
397                         }
398                 arg=sv_mortalcopy(ST(1));
399                 SvREFCNT_inc(arg);
400                 BIO_set_ex_data(bio,p5_bio_ex_bio_callback,(char *)arg);
401                 BIO_set_callback(bio,p5_bio_callback);
402
403 void
404 p5_BIO_DESTROY(bio)
405         BIO *bio
406         PREINIT:
407                 SV *sv;
408         PPCODE:
409                 pr_name_d("p5_BIO_DESTROY",bio->references);
410                 printf("p5_BIO_DESTROY <%s> %d\n",bio->method->name,bio->references);
411                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,NULL);
412                 BIO_free_all(bio);
413
414 int
415 p5_BIO_set_ssl(bio,ssl)
416         BIO *bio;
417         SSL *ssl;
418         CODE:
419                 pr_name("p5_BIO_set_ssl");
420                 ssl->references++;
421                 RETVAL=BIO_set_ssl(bio,ssl,BIO_CLOSE);
422         OUTPUT:
423                 RETVAL
424
425 int
426 p5_BIO_number_read(bio)
427         BIO *bio;
428         CODE:
429                 RETVAL=BIO_number_read(bio);
430         OUTPUT:
431                 RETVAL
432
433 int
434 p5_BIO_number_written(bio)
435         BIO *bio;
436         CODE:
437                 RETVAL=BIO_number_written(bio);
438         OUTPUT:
439                 RETVAL
440
441 int
442 p5_BIO_references(bio)
443         BIO *bio;
444         CODE:
445                 RETVAL=bio->references; 
446         OUTPUT:
447                 RETVAL
448