1 /*****
2 *
3 * Copyright (C) 2001-2015 CS-SI. All Rights Reserved.
4 * Author: Yoann Vandoorselaere <yoann.v@prelude-ids.com>
5 *
6 * This file is part of the Prelude library.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 *****/
23
24 #include "config.h"
25 #include "libmissing.h"
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <netinet/in.h>
33 #include <poll.h>
34 #include <sys/ioctl.h>
35 #include <gnutls/gnutls.h>
36
37 #include "prelude-inttypes.h"
38
39 #ifdef HAVE_SYS_FILIO_H
40 # include <sys/filio.h>
41 #endif
42
43
44 #include "prelude-log.h"
45 #include "prelude-io.h"
46 #include "common.h"
47
48
49 #define PRELUDE_ERROR_SOURCE_DEFAULT PRELUDE_ERROR_SOURCE_IO
50 #include "prelude-error.h"
51
52
53 #define CHUNK_SIZE 1024
54
55 #ifndef MIN
56 # define MIN(x, y) ((x) < (y) ? (x) : (y))
57 #endif
58
59 struct prelude_io {
60
61 int fd;
62 void *fd_ptr;
63
64 size_t size;
65 size_t rindex;
66
67 int (*close)(prelude_io_t *pio);
68 ssize_t (*read)(prelude_io_t *pio, void *buf, size_t count);
69 ssize_t (*write)(prelude_io_t *pio, const void *buf, size_t count);
70 ssize_t (*pending)(prelude_io_t *pio);
71 };
72
73
74
75 /*
76 * Buffer IO functions.
77 */
buffer_read(prelude_io_t * pio,void * buf,size_t count)78 static ssize_t buffer_read(prelude_io_t *pio, void *buf, size_t count)
79 {
80 if ( pio->size - pio->rindex == 0 )
81 return 0;
82
83 count = MIN(count, pio->size - pio->rindex);
84
85 memcpy(buf, (unsigned char *) pio->fd_ptr + pio->rindex, count);
86 pio->rindex += count;
87
88 return count;
89 }
90
91
92
buffer_write(prelude_io_t * pio,const void * buf,size_t count)93 static ssize_t buffer_write(prelude_io_t *pio, const void *buf, size_t count)
94 {
95 unsigned char *new;
96
97 if ( pio->size + count <= pio->size )
98 return -1;
99
100 new = _prelude_realloc(pio->fd_ptr, pio->size + count);
101 if ( ! new )
102 return prelude_error_from_errno(errno);
103
104 memcpy(new + pio->size, buf, count);
105
106 pio->fd_ptr = new;
107 pio->size += count;
108
109 return count;
110 }
111
112
113
buffer_close(prelude_io_t * pio)114 static int buffer_close(prelude_io_t *pio)
115 {
116 if ( pio->fd_ptr ) {
117 free(pio->fd_ptr);
118 pio->fd_ptr = NULL;
119 pio->size = pio->rindex = 0;
120 }
121
122 return 0;
123 }
124
125
126
buffer_pending(prelude_io_t * pio)127 static ssize_t buffer_pending(prelude_io_t *pio)
128 {
129 return pio->size - pio->rindex;
130 }
131
132
133
134
135 /*
136 * System IO functions.
137 */
sys_read(prelude_io_t * pio,void * buf,size_t count)138 static ssize_t sys_read(prelude_io_t *pio, void *buf, size_t count)
139 {
140 ssize_t ret;
141
142 do {
143 ret = read(pio->fd, buf, count);
144 } while ( ret < 0 && errno == EINTR );
145
146 if ( ret == 0 )
147 return prelude_error(PRELUDE_ERROR_EOF);
148
149 if ( ret < 0 ) {
150 #ifdef ECONNRESET
151 if ( errno == ECONNRESET )
152 return prelude_error(PRELUDE_ERROR_EOF);
153 #endif
154 return prelude_error_from_errno(errno);
155 }
156
157 return ret;
158 }
159
160
161
sys_write(prelude_io_t * pio,const void * buf,size_t count)162 static ssize_t sys_write(prelude_io_t *pio, const void *buf, size_t count)
163 {
164 ssize_t ret;
165
166 do {
167 ret = write(pio->fd, buf, count);
168 } while ( ret < 0 && errno == EINTR );
169
170 if ( ret < 0 )
171 return prelude_error_from_errno(errno);
172
173 return ret;
174 }
175
176
177
sys_close(prelude_io_t * pio)178 static int sys_close(prelude_io_t *pio)
179 {
180 int ret;
181
182 do {
183 ret = close(pio->fd);
184 } while ( ret < 0 && errno == EINTR );
185
186 return (ret >= 0) ? ret : prelude_error_from_errno(errno);
187 }
188
189
190
sys_pending(prelude_io_t * pio)191 static ssize_t sys_pending(prelude_io_t *pio)
192 {
193 long ret = 0;
194
195 if ( ioctl(pio->fd, FIONREAD, &ret) < 0 )
196 return prelude_error_from_errno(errno);
197
198 return ret;
199 }
200
201
202
203
204 /*
205 * Buffered IO functions.
206 */
file_read(prelude_io_t * pio,void * buf,size_t count)207 static ssize_t file_read(prelude_io_t *pio, void *buf, size_t count)
208 {
209 FILE *fd;
210 size_t ret;
211
212 /*
213 * ferror / clearerror can be macro that might dereference fd_ptr.
214 */
215 fd = pio->fd_ptr;
216 prelude_return_val_if_fail(fd, prelude_error(PRELUDE_ERROR_ASSERTION));
217
218 ret = fread(buf, count, 1, fd);
219 if ( ret <= 0 ) {
220 ret = ferror(fd) ? prelude_error_from_errno(errno) : prelude_error(PRELUDE_ERROR_EOF);
221 clearerr(fd);
222 return ret;
223 }
224
225 /*
226 * fread return the number of *item* read.
227 */
228 return count;
229 }
230
231
232
file_write(prelude_io_t * pio,const void * buf,size_t count)233 static ssize_t file_write(prelude_io_t *pio, const void *buf, size_t count)
234 {
235 size_t ret;
236
237 prelude_return_val_if_fail(pio->fd_ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
238
239 ret = fwrite(buf, count, 1, pio->fd_ptr);
240 if ( ret <= 0 )
241 return ret;
242
243 /*
244 * fwrite return the number of *item* written.
245 */
246 return count;
247 }
248
249
250
file_close(prelude_io_t * pio)251 static int file_close(prelude_io_t *pio)
252 {
253 prelude_return_val_if_fail(pio->fd_ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
254 return fclose(pio->fd_ptr);
255 }
256
257
258
file_pending(prelude_io_t * pio)259 static ssize_t file_pending(prelude_io_t *pio)
260 {
261 #ifdef ENOTSUP
262 return prelude_error_from_errno(ENOTSUP);
263 #else
264 return prelude_error(PRELUDE_ERROR_GENERIC);
265 #endif
266 }
267
268
269
270 /*
271 * TLS IO functions
272 */
tls_check_error(prelude_io_t * pio,int error)273 static int tls_check_error(prelude_io_t *pio, int error)
274 {
275 int ret = 0;
276 const char *alert;
277
278 switch(error) {
279 case GNUTLS_E_AGAIN:
280 ret = prelude_error(PRELUDE_ERROR_EAGAIN);
281 break;
282
283 case GNUTLS_E_WARNING_ALERT_RECEIVED:
284 alert = gnutls_alert_get_name(gnutls_alert_get(pio->fd_ptr));
285 ret = prelude_error_verbose(PRELUDE_ERROR_TLS_WARNING_ALERT, "TLS warning alert from peer: %s", alert);
286 break;
287
288 case GNUTLS_E_FATAL_ALERT_RECEIVED:
289 alert = gnutls_alert_get_name(gnutls_alert_get(pio->fd_ptr));
290 ret = prelude_error_verbose(PRELUDE_ERROR_TLS_FATAL_ALERT, "TLS fatal alert from peer: %s", alert);
291 break;
292
293 case GNUTLS_E_PUSH_ERROR:
294 case GNUTLS_E_PULL_ERROR:
295 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH:
296 ret = prelude_error(PRELUDE_ERROR_EOF);
297 break;
298
299 default:
300 ret = prelude_error_verbose(PRELUDE_ERROR_TLS, "TLS: %s", gnutls_strerror(error));
301 }
302
303 /*
304 * If the error is fatal, deinitialize the session and revert
305 * to system IO. The caller is then expected to call prelude_io_close()
306 * again until it return 0.
307 *
308 * If it's non fatal, simply return the error. The caller is supposed
309 * to resume the prelude_io_close() call still.
310 */
311 if ( gnutls_error_is_fatal(error) ) {
312 gnutls_deinit(pio->fd_ptr);
313 prelude_io_set_sys_io(pio, pio->fd);
314 }
315
316 return ret;
317 }
318
319
320
tls_read(prelude_io_t * pio,void * buf,size_t count)321 static ssize_t tls_read(prelude_io_t *pio, void *buf, size_t count)
322 {
323 ssize_t ret;
324
325 do {
326 ret = gnutls_record_recv(pio->fd_ptr, buf, count);
327 } while ( ret < 0 && ret == GNUTLS_E_INTERRUPTED );
328
329 if ( ret < 0 )
330 return tls_check_error(pio, ret);
331
332 if ( ret == 0 )
333 return prelude_error(PRELUDE_ERROR_EOF);
334
335 return ret;
336 }
337
338
339
tls_write(prelude_io_t * pio,const void * buf,size_t count)340 static ssize_t tls_write(prelude_io_t *pio, const void *buf, size_t count)
341 {
342 ssize_t ret;
343
344 do {
345 ret = gnutls_record_send(pio->fd_ptr, buf, count);
346 } while ( ret < 0 && ret == GNUTLS_E_INTERRUPTED );
347
348 if ( ret < 0 )
349 return tls_check_error(pio, ret);
350
351 return ret;
352 }
353
354
355
tls_close(prelude_io_t * pio)356 static int tls_close(prelude_io_t *pio)
357 {
358 int ret;
359
360 do {
361 ret = gnutls_bye(pio->fd_ptr, GNUTLS_SHUT_RDWR);
362 } while ( ret < 0 && ret == GNUTLS_E_INTERRUPTED );
363
364 if ( ret < 0 ) {
365 ret = tls_check_error(pio, ret);
366 if ( prelude_io_is_error_fatal(pio, ret) )
367 sys_close(pio);
368
369 return ret;
370 }
371
372 gnutls_deinit(pio->fd_ptr);
373
374 /*
375 * this is not expected to fail
376 */
377 prelude_io_set_sys_io(pio, pio->fd);
378 return sys_close(pio);
379 }
380
381
382
tls_pending(prelude_io_t * pio)383 static ssize_t tls_pending(prelude_io_t *pio)
384 {
385 ssize_t ret;
386
387 ret = gnutls_record_check_pending(pio->fd_ptr);
388 if ( ret > 0 )
389 return ret;
390
391 ret = sys_pending(pio);
392 if ( ret > 0 )
393 return ret;
394
395 return 0;
396 }
397
398
399
400 /*
401 * Forward data from one fd to another using copy.
402 */
copy_forward(prelude_io_t * dst,prelude_io_t * src,size_t count)403 static ssize_t copy_forward(prelude_io_t *dst, prelude_io_t *src, size_t count)
404 {
405 int ret;
406 size_t scount;
407 unsigned char buf[8192];
408
409 scount = count;
410
411 while ( count ) {
412
413 ret = (count < sizeof(buf)) ? count : sizeof(buf);
414
415 ret = prelude_io_read(src, buf, ret);
416 if ( ret <= 0 )
417 return ret;
418
419 count -= ret;
420
421 ret = prelude_io_write(dst, buf, ret);
422 if ( ret < 0 )
423 return ret;
424 }
425
426 return scount;
427 }
428
429
430
431
432
433 /**
434 * prelude_io_forward:
435 * @src: Pointer to a #prelude_io_t object.
436 * @dst: Pointer to a #prelude_io_t object.
437 * @count: Number of byte to forward from @src to @dst.
438 *
439 * prelude_io_forward() attempts to transfer up to @count bytes from
440 * the file descriptor identified by @src into the file descriptor
441 * identified by @dst.
442 *
443 * Returns: If the transfer was successful, the number of bytes written
444 * to @dst is returned. On error, -1 is returned, and errno is set appropriately.
445 */
prelude_io_forward(prelude_io_t * dst,prelude_io_t * src,size_t count)446 ssize_t prelude_io_forward(prelude_io_t *dst, prelude_io_t *src, size_t count)
447 {
448 prelude_return_val_if_fail(dst, prelude_error(PRELUDE_ERROR_ASSERTION));
449 prelude_return_val_if_fail(src, prelude_error(PRELUDE_ERROR_ASSERTION));
450
451 return copy_forward(dst, src, count);
452 }
453
454
455
456
457 /**
458 * prelude_io_read:
459 * @pio: Pointer to a #prelude_io_t object.
460 * @buf: Pointer to the buffer to store data into.
461 * @count: Number of bytes to read.
462 *
463 * prelude_io_read() attempts to read up to @count bytes from the
464 * file descriptor identified by @pio into the buffer starting at @buf.
465 *
466 * If @count is zero, prelude_io_read() returns zero and has no other
467 * results. If @count is greater than SSIZE_MAX, the result is unspecified.
468 *
469 * The case where the read function would be interrupted by a signal is
470 * handled internally. So you don't have to check for EINTR.
471 *
472 * Returns: On success, the number of bytes read is returned (zero
473 * indicates end of file). It is not an error if this number is smaller
474 * than the number of bytes requested; this may happen for example because
475 * fewer bytes are actually available right now or because read() was
476 * interrupted by a signal.
477 *
478 * On error, a negative value is returned. In this case it is left unspecified
479 * whether the file position (if any) changes.
480 */
prelude_io_read(prelude_io_t * pio,void * buf,size_t count)481 ssize_t prelude_io_read(prelude_io_t *pio, void *buf, size_t count)
482 {
483 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
484 prelude_return_val_if_fail(pio->read, prelude_error(PRELUDE_ERROR_ASSERTION));
485 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
486
487 return pio->read(pio, buf, count);
488 }
489
490
491
492
493 /**
494 * prelude_io_read_wait:
495 * @pio: Pointer to a #prelude_io_t object.
496 * @buf: Pointer to the buffer to store data into.
497 * @count: Number of bytes to read.
498 *
499 * prelude_io_read_wait() attempts to read up to @count bytes from the
500 * file descriptor identified by @pio into the buffer starting at @buf.
501 *
502 * If @count is zero, prelude_io_read() returns zero and has no other
503 * results. If @count is greater than SSIZE_MAX, the result is unspecified.
504 *
505 * The case where the read function would be interrupted by a signal is
506 * handled internally. So you don't have to check for EINTR.
507 *
508 * prelude_io_read_wait() always return the number of bytes requested.
509 * Be carefull that this function is blocking.
510 *
511 * Returns: On success, the number of bytes read is returned (zero
512 * indicates end of file).
513 *
514 * On error, -1 is returned, and errno is set appropriately. In this
515 * case it is left unspecified whether the file position (if any) changes.
516 */
prelude_io_read_wait(prelude_io_t * pio,void * buf,size_t count)517 ssize_t prelude_io_read_wait(prelude_io_t *pio, void *buf, size_t count)
518 {
519 ssize_t ret;
520 size_t n = 0;
521 struct pollfd pfd;
522 unsigned char *in = buf;
523
524 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
525 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
526
527 pfd.fd = prelude_io_get_fd(pio);
528 pfd.events = POLLIN;
529
530 do {
531 ret = poll(&pfd, 1, -1);
532 if ( ret < 0 )
533 return prelude_error_from_errno(errno);
534
535 if ( ! (pfd.revents & POLLIN) )
536 return prelude_error_verbose(PRELUDE_ERROR_GENERIC, "expected POLLIN event");
537
538 ret = prelude_io_read(pio, &in[n], count - n);
539 if ( ret < 0 )
540 return ret;
541
542 n += (size_t) ret;
543
544 } while ( n != count );
545
546 return (ssize_t) n;
547 }
548
549
550
551 /**
552 * prelude_io_read_delimited:
553 * @pio: Pointer to a #prelude_io_t object.
554 * @buf: Pointer to the address of a buffer to store address of data into.
555 *
556 * prelude_io_read_delimited() read message written by prelude_write_delimited().
557 * Theses messages are sents along with the len of the message.
558 *
559 * Uppon return the @buf argument is updated to point on a newly allocated
560 * buffer containing the data read. The @count argument is set to the number of
561 * bytes the message was containing.
562 *
563 * The case where the read function would be interrupted by a signal is
564 * handled internally. So you don't have to check for EINTR.
565 *
566 * Returns: On success, the number of bytes read is returned (zero
567 * indicates end of file).
568 *
569 * On error, -1 is returned, and errno is set appropriately. In this
570 * case it is left unspecified whether the file position (if any) changes.
571 */
prelude_io_read_delimited(prelude_io_t * pio,unsigned char ** buf)572 ssize_t prelude_io_read_delimited(prelude_io_t *pio, unsigned char **buf)
573 {
574 ssize_t ret;
575 size_t count;
576 uint16_t msglen;
577
578 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
579
580 ret = prelude_io_read_wait(pio, &msglen, sizeof(msglen));
581 if ( ret <= 0 )
582 return ret;
583
584 count = ntohs(msglen);
585
586 *buf = malloc(count);
587 if ( ! *buf )
588 return prelude_error_from_errno(errno);
589
590 ret = prelude_io_read_wait(pio, *buf, count);
591 if ( ret < 0 )
592 return ret;
593
594 return count;
595 }
596
597
598
599
600 /**
601 * prelude_io_write:
602 * @pio: Pointer to a #prelude_io_t object.
603 * @buf: Pointer to the buffer to write data from.
604 * @count: Number of bytes to write.
605 *
606 * prelude_io_write() writes up to @count bytes to the file descriptor
607 * identified by @pio from the buffer starting at @buf. POSIX requires
608 * that a read() which can be proved to occur after a write() has returned
609 * returns the new data. Note that not all file systems are POSIX conforming.
610 *
611 * The case where the write() function would be interrupted by a signal is
612 * handled internally. So you don't have to check for EINTR.
613 *
614 * Returns: On success, the number of bytes written are returned (zero
615 * indicates nothing was written). On error, -1 is returned, and errno
616 * is set appropriately. If @count is zero and the file descriptor refers
617 * to a regular file, 0 will be returned without causing any other effect.
618 * For a special file, the results are not portable.
619 */
prelude_io_write(prelude_io_t * pio,const void * buf,size_t count)620 ssize_t prelude_io_write(prelude_io_t *pio, const void *buf, size_t count)
621 {
622 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
623 prelude_return_val_if_fail(pio->write, prelude_error(PRELUDE_ERROR_ASSERTION));
624 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
625
626 return pio->write(pio, buf, count);
627 }
628
629
630
631 /**
632 * prelude_io_write_delimited:
633 * @pio: Pointer to a #prelude_io_t object.
634 * @buf: Pointer to the buffer to write data from.
635 * @count: Number of bytes to write.
636 *
637 * prelude_io_write_delimited() writes up to @count bytes to the file descriptor
638 * identified by @pio from the buffer starting at @buf. POSIX requires
639 * that a read() which can be proved to occur after a write() has returned
640 * returns the new data. Note that not all file systems are POSIX conforming.
641 *
642 * prelude_io_write_delimited() also write the len of the data to be sent.
643 * which allow prelude_io_read_delimited() to safely know if it got all the
644 * data a given write contain.
645 *
646 * The case where the write() function would be interrupted by a signal is
647 * handled internally. So you don't have to check for EINTR.
648 *
649 * Returns: On success, the number of bytes written are returned (zero
650 * indicates nothing was written). On error, -1 is returned, and errno
651 * is set appropriately.
652 */
prelude_io_write_delimited(prelude_io_t * pio,const void * buf,uint16_t count)653 ssize_t prelude_io_write_delimited(prelude_io_t *pio, const void *buf, uint16_t count)
654 {
655 int ret;
656 uint16_t nlen;
657
658 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
659 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
660
661 nlen = htons(count);
662
663 ret = prelude_io_write(pio, &nlen, sizeof(nlen));
664 if ( ret <= 0 )
665 return ret;
666
667 ret = prelude_io_write(pio, buf, count);
668 if ( ret <= 0 )
669 return ret;
670
671 return count;
672 }
673
674
675
676
677 /**
678 * prelude_io_close:
679 * @pio: Pointer to a #prelude_io_t object.
680 *
681 * prelude_io_close() closes the file descriptor indentified by @pio,
682 *
683 * The case where the close() function would be interrupted by a signal is
684 * handled internally. So you don't have to check for EINTR.
685 *
686 * However, and especially when the underlaying layer is TLS, prelude_io_close()
687 * might return error. If this happen, you should continue calling the function
688 * until it return zero.
689 *
690 * Returns: zero on success, or -1 if an error occurred.
691 */
prelude_io_close(prelude_io_t * pio)692 int prelude_io_close(prelude_io_t *pio)
693 {
694 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
695 prelude_return_val_if_fail(pio->close, prelude_error(PRELUDE_ERROR_ASSERTION));
696
697 return pio->close(pio);
698 }
699
700
701
702
703 /**
704 * prelude_io_new:
705 * @ret: Pointer where to store the created #prelude_io_t object.
706 *
707 * Create a new prelude IO object.
708 *
709 * Returns: 0 on success, or a negative value if an error occur.
710 */
prelude_io_new(prelude_io_t ** ret)711 int prelude_io_new(prelude_io_t **ret)
712 {
713 *ret = calloc(1, sizeof(**ret));
714 if ( ! *ret )
715 return prelude_error_from_errno(errno);
716
717 return 0;
718 }
719
720
721
722 /**
723 * prelude_io_set_file_io:
724 * @pio: A pointer on the #prelude_io_t object.
725 * @fd: File descriptor identifying a file.
726 *
727 * Setup the @pio object to work with file I/O function.
728 * The @pio object is then associated with @fd.
729 */
prelude_io_set_file_io(prelude_io_t * pio,FILE * fdptr)730 void prelude_io_set_file_io(prelude_io_t *pio, FILE *fdptr)
731 {
732 prelude_return_if_fail(pio);
733 prelude_return_if_fail(fdptr);
734
735 pio->fd = fileno(fdptr);
736 pio->fd_ptr = fdptr;
737 pio->read = file_read;
738 pio->write = file_write;
739 pio->close = file_close;
740 pio->pending = file_pending;
741 }
742
743
744
745
746 /**
747 * prelude_io_set_tls_io:
748 * @pio: A pointer on the #prelude_io_t object.
749 * @tls: Pointer on the TLS structure holding the TLS connection data.
750 *
751 * Setup the @pio object to work with TLS based I/O function.
752 * The @pio object is then associated with @tls.
753 */
prelude_io_set_tls_io(prelude_io_t * pio,void * tls)754 void prelude_io_set_tls_io(prelude_io_t *pio, void *tls)
755 {
756 union {
757 void *ptr;
758 int fd;
759 } data;
760
761 prelude_return_if_fail(pio);
762 prelude_return_if_fail(tls);
763
764 data.ptr = gnutls_transport_get_ptr(tls);
765 pio->fd = data.fd;
766
767 pio->fd_ptr = tls;
768 pio->read = tls_read;
769 pio->write = tls_write;
770 pio->close = tls_close;
771 pio->pending = tls_pending;
772 }
773
774
775
776
777 /**
778 * prelude_io_set_sys_io:
779 * @pio: A pointer on the #prelude_io_t object.
780 * @fd: A file descriptor.
781 *
782 * Setup the @pio object to work with system based I/O function.
783 * The @pio object is then associated with @fd.
784 */
prelude_io_set_sys_io(prelude_io_t * pio,int fd)785 void prelude_io_set_sys_io(prelude_io_t *pio, int fd)
786 {
787 prelude_return_if_fail(pio);
788
789 pio->fd = fd;
790 pio->fd_ptr = NULL;
791 pio->read = sys_read;
792 pio->write = sys_write;
793 pio->close = sys_close;
794 pio->pending = sys_pending;
795 }
796
797
798
prelude_io_set_buffer_io(prelude_io_t * pio)799 int prelude_io_set_buffer_io(prelude_io_t *pio)
800 {
801 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
802
803 pio->fd_ptr = NULL;
804 pio->size = pio->rindex = 0;
805
806 pio->read = buffer_read;
807 pio->write = buffer_write;
808 pio->close = buffer_close;
809 pio->pending = buffer_pending;
810
811 return 0;
812 }
813
814
815
816 /**
817 * prelude_io_get_fd:
818 * @pio: A pointer on a #prelude_io_t object.
819 *
820 * Returns: The FD associated with this object.
821 */
prelude_io_get_fd(prelude_io_t * pio)822 int prelude_io_get_fd(prelude_io_t *pio)
823 {
824 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
825 return pio->fd;
826 }
827
828
829
830 /**
831 * prelude_io_get_fdptr:
832 * @pio: A pointer on a #prelude_io_t object.
833 *
834 * Returns: Pointer associated with this object (file, tls, buffer, or NULL).
835 */
prelude_io_get_fdptr(prelude_io_t * pio)836 void *prelude_io_get_fdptr(prelude_io_t *pio)
837 {
838 prelude_return_val_if_fail(pio, NULL);
839 return pio->fd_ptr;
840 }
841
842
843
844 /**
845 * prelude_io_destroy:
846 * @pio: Pointer to a #prelude_io_t object.
847 *
848 * Destroy the @pio object.
849 */
prelude_io_destroy(prelude_io_t * pio)850 void prelude_io_destroy(prelude_io_t *pio)
851 {
852 prelude_return_if_fail(pio);
853 free(pio);
854 }
855
856
857
858
859 /**
860 * prelude_io_pending:
861 * @pio: Pointer to a #prelude_io_t object.
862 *
863 * prelude_io_pending return the number of bytes waiting to
864 * be read on an TLS or socket fd.
865 *
866 * Returns: Number of byte waiting to be read on @pio, or -1
867 * if @pio is not of type TLS or socket.
868 */
prelude_io_pending(prelude_io_t * pio)869 ssize_t prelude_io_pending(prelude_io_t *pio)
870 {
871 prelude_return_val_if_fail(pio, prelude_error(PRELUDE_ERROR_ASSERTION));
872 return pio->pending(pio);
873 }
874
875
876
877
878 /**
879 * prelude_io_is_error_fatal:
880 * @pio: Pointer to a #prelude_io_t object.
881 * @error: Error returned by one of the #prelude_io_t function.
882 *
883 * Check whether the returned error is fatal, or not.
884 *
885 * Returns: TRUE if error is fatal, FALSE if it is not.
886 */
prelude_io_is_error_fatal(prelude_io_t * pio,int error)887 prelude_bool_t prelude_io_is_error_fatal(prelude_io_t *pio, int error)
888 {
889 prelude_error_code_t code;
890
891 prelude_return_val_if_fail(pio, FALSE);
892
893 if ( ! error )
894 return FALSE;
895
896 code = prelude_error_get_code(error);
897 if ( code == PRELUDE_ERROR_EAGAIN || code == PRELUDE_ERROR_EINTR || code == PRELUDE_ERROR_TLS_WARNING_ALERT )
898 return FALSE;
899
900 return TRUE;
901 }
902
903
904
905 /**
906 * prelude_io_set_write_callback:
907 * @pio: Pointer to a #prelude_io_t object.
908 * @write: Callback function to be called on prelude_io_write().
909 *
910 * Set an user defined write callback function to be called on
911 * prelude_io_write().
912 */
prelude_io_set_write_callback(prelude_io_t * pio,ssize_t (* write)(prelude_io_t * io,const void * buf,size_t count))913 void prelude_io_set_write_callback(prelude_io_t *pio, ssize_t (*write)(prelude_io_t *io, const void *buf, size_t count))
914 {
915 pio->write = write;
916 }
917
918
919 /**
920 * prelude_io_set_read_callback:
921 * @pio: Pointer to a #prelude_io_t object.
922 * @read: Callback function to be called on prelude_io_read().
923 *
924 * Set an user defined read callback function to be called on
925 * prelude_io_read().
926 */
prelude_io_set_read_callback(prelude_io_t * pio,ssize_t (* read)(prelude_io_t * io,void * buf,size_t count))927 void prelude_io_set_read_callback(prelude_io_t *pio, ssize_t (*read)(prelude_io_t *io, void *buf, size_t count))
928 {
929 pio->read = read;
930 }
931
932
933
934 /**
935 * prelude_io_set_pending_callback:
936 * @pio: Pointer to a #prelude_io_t object.
937 * @pending: Callback function to be called on prelude_io_pending().
938 *
939 * Set an user defined read callback function to be called on
940 * prelude_io_pending().
941 */
prelude_io_set_pending_callback(prelude_io_t * pio,ssize_t (* pending)(prelude_io_t * io))942 void prelude_io_set_pending_callback(prelude_io_t *pio, ssize_t (*pending)(prelude_io_t *io))
943 {
944 pio->pending = pending;
945 }
946
947
948
949 /**
950 * prelude_io_set_fdptr:
951 * @pio: Pointer to a #prelude_io_t object.
952 * @ptr: Pointer to user defined data.
953 *
954 * Set an user defined pointer that might be retrieved using
955 * prelude_io_get_fdptr().
956 */
prelude_io_set_fdptr(prelude_io_t * pio,void * ptr)957 void prelude_io_set_fdptr(prelude_io_t *pio, void *ptr)
958 {
959 pio->fd_ptr = ptr;
960 }
961