The dir is named util/ and better to explicitly call the
[openssl.git] / perl / 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(sv_2mortal(newSViv(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,
64                         ex_cleanup);
65         p5_bio_ex_bio_callback= 
66                 BIO_get_ex_new_index(0,"bio_callback",NULL,NULL,
67                         ex_cleanup);
68         p5_bio_ex_bio_callback_data=
69                 BIO_get_ex_new_index(0,"bio_callback_data",NULL,NULL,
70                         ex_cleanup);
71         return(1);
72         }
73
74 MODULE =  SSLeay::BIO   PACKAGE = SSLeay::BIO PREFIX = p5_BIO_
75
76 VERSIONCHECK: DISABLE
77
78 void
79 p5_BIO_new_buffer_ssl_connect(...)
80         PREINIT:
81                 SSL_CTX *ctx;
82                 BIO *bio;
83                 SV *arg;
84         PPCODE:
85                 if (items == 1)
86                         arg=ST(0);
87                 else if (items == 2)
88                         arg=ST(1);
89                 else
90                         arg=NULL;
91
92                 if ((arg == NULL) || !(sv_derived_from(arg,"SSLeay::SSL::CTX")))
93                         croak("Usage: SSLeay::BIO::new_buffer_ssl_connect(SSL_CTX)");
94                 else
95                         {
96                         IV tmp=SvIV((SV *)SvRV(arg));
97                         ctx=(SSL_CTX *)tmp;
98                         }
99                 EXTEND(sp,1);
100                 bio=BIO_new_buffer_ssl_connect(ctx);
101                 arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
102                 PUSHs(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=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
128                 PUSHs(arg);
129
130 void
131 p5_BIO_new(...)
132         PREINIT:
133                 BIO *bio;
134                 char *type;
135                 SV *arg;
136         PPCODE:
137                 pr_name("p5_BIO_new");
138                 if ((items == 1) && SvPOK(ST(0)))
139                         type=SvPV(ST(0),na);
140                 else if ((items == 2) && SvPOK(ST(1)))
141                         type=SvPV(ST(1),na);
142                 else
143                         croak("Usage: SSLeay::BIO::new(type)");
144
145                 EXTEND(sp,1);
146                 if (strcmp(type,"connect") == 0)
147                         bio=BIO_new(BIO_s_connect());
148                 else if (strcmp(type,"accept") == 0)
149                         bio=BIO_new(BIO_s_accept());
150                 else if (strcmp(type,"ssl") == 0)
151                         bio=BIO_new(BIO_f_ssl());
152                 else if (strcmp(type,"buffer") == 0)
153                         bio=BIO_new(BIO_f_buffer());
154                 else
155                         croak("unknown BIO type");
156                 arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
157                 PUSHs(arg);
158
159 int
160 p5_BIO_hostname(bio,name)
161         BIO *bio;
162         char *name;
163         CODE:
164                 RETVAL=BIO_set_conn_hostname(bio,name);
165         OUTPUT:
166                 RETVAL
167
168 int
169 p5_BIO_set_accept_port(bio,str)
170         BIO *bio;
171         char *str;
172         CODE:
173                 RETVAL=BIO_set_accept_port(bio,str);
174         OUTPUT:
175                 RETVAL
176
177 int
178 p5_BIO_do_handshake(bio)
179         BIO *bio;
180         CODE:
181                 RETVAL=BIO_do_handshake(bio);
182         OUTPUT:
183                 RETVAL
184
185 BIO *
186 p5_BIO_push(b,bio)
187         BIO *b;
188         BIO *bio;
189         CODE:
190                 /* This reference will be reduced when the reference is
191                  * let go, and then when the BIO_free_all() is called
192                  * inside the SSLeay library by the BIO with this
193                  * pushed into */
194                 bio->references++;
195                 RETVAL=BIO_push(b,bio);
196         OUTPUT:
197                 RETVAL
198
199 void
200 p5_BIO_pop(b)
201         BIO *b
202         PREINIT:
203                 BIO *bio;
204                 char *type;
205                 SV *arg;
206         PPCODE:
207                 bio=BIO_pop(b);
208                 if (bio != NULL)
209                         {
210                         /* This BIO will either be one created in the
211                          * perl library, in which case it will have a perl
212                          * SV, otherwise it will have been created internally,
213                          * inside SSLeay.  For the 'pushed in', it needs
214                          * the reference count decememted. */
215                         arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
216                         if (arg == NULL)
217                                 {
218                                 arg=new_ref("SSLeay::BIO",(char *)bio,0);
219                                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
220                                 PUSHs(arg);
221                                 }
222                         else
223                                 {
224                                 /* it was pushed in */
225                                 SvREFCNT_inc(arg);
226                                 PUSHs(arg);
227 #if 0           /* This does not need to be done. */
228                                 if (bio->references < 1)
229                                         abort();
230                                 /* decrement the reference count */
231                                 BIO_free(bio);
232 #endif
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                                         croak("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                                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
360                                 bio->references++;
361                                 PUSHs(arg);
362                                 }
363                         else
364                                 {
365                                 SvREFCNT_inc(arg);
366                                 PUSHs(arg);
367                                 }
368                         }
369
370 int
371 p5_BIO_puts(bio,in)
372         BIO *bio;
373         SV *in;
374         PREINIT:
375                 char *ptr;
376         CODE:
377                 ptr=SvPV(in,na);
378                 RETVAL=BIO_puts(bio,ptr);
379         OUTPUT:
380                 RETVAL
381
382 void
383 p5_BIO_set_callback(bio,cb,...)
384         BIO *bio;
385         SV *cb;
386         PREINIT:
387                 SV *arg=NULL;
388                 SV *arg2=NULL;
389         CODE:
390                 if (items > 3)
391                         croak("Usage: SSLeay::BIO::set_callback(bio,callback[,arg]");
392                 if (items == 3)
393                         {
394                         arg2=sv_mortalcopy(ST(2));
395                         SvREFCNT_inc(arg2);
396                         BIO_set_ex_data(bio,p5_bio_ex_bio_callback_data,
397                                 (char *)arg2);
398                         }
399                 arg=sv_mortalcopy(ST(1));
400                 SvREFCNT_inc(arg);
401                 BIO_set_ex_data(bio,p5_bio_ex_bio_callback,(char *)arg);
402                 printf("%08lx < bio_ptr\n",BIO_get_ex_data(bio,p5_bio_ex_bio_ptr));
403                 BIO_set_callback(bio,p5_bio_callback);
404
405 void
406 p5_BIO_DESTROY(bio)
407         BIO *bio
408         PREINIT:
409                 SV *sv;
410         PPCODE:
411                 pr_name_d("p5_BIO_DESTROY",bio->references);
412                 printf("p5_BIO_DESTROY <%s> %d\n",bio->method->name,bio->references);
413                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,NULL);
414                 BIO_free_all(bio);
415
416 int
417 p5_BIO_set_ssl(bio,ssl)
418         BIO *bio;
419         SSL *ssl;
420         CODE:
421                 pr_name("p5_BIO_set_ssl");
422                 ssl->references++;
423                 RETVAL=BIO_set_ssl(bio,ssl,BIO_CLOSE);
424         OUTPUT:
425                 RETVAL
426
427 int
428 p5_BIO_number_read(bio)
429         BIO *bio;
430         CODE:
431                 RETVAL=BIO_number_read(bio);
432         OUTPUT:
433                 RETVAL
434
435 int
436 p5_BIO_number_written(bio)
437         BIO *bio;
438         CODE:
439                 RETVAL=BIO_number_written(bio);
440         OUTPUT:
441                 RETVAL
442
443 int
444 p5_BIO_references(bio)
445         BIO *bio;
446         CODE:
447                 RETVAL=bio->references; 
448         OUTPUT:
449                 RETVAL
450