Branch data Line data Source code
1 : : /**
2 : : * \file
3 : : *
4 : : * \author Georg Hopp
5 : : *
6 : : * \copyright
7 : : * Copyright © 2012 Georg Hopp
8 : : *
9 : : * This program is free software: you can redistribute it and/or modify
10 : : * it under the terms of the GNU General Public License as published by
11 : : * the Free Software Foundation, either version 3 of the License, or
12 : : * (at your option) any later version.
13 : : *
14 : : * This program is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : : * GNU General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU General Public License
20 : : * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : : */
22 : :
23 : : #include <openssl/err.h>
24 : : #include <openssl/ssl.h>
25 : : #include <unistd.h>
26 : : #include <errno.h>
27 : :
28 : : #include "stream.h"
29 : : #include "logger.h"
30 : :
31 : : extern Logger logger;
32 : :
33 : :
34 : : ssize_t
35 : 0 : streamRead(Stream this, void * buf, size_t count)
36 : : {
37 : : ssize_t done;
38 : :
39 : 0 : switch(this->type) {
40 : : ssize_t _read;
41 : :
42 : : case STREAM_FD:
43 : 0 : _read = read((this->handle).fd, buf, count);
44 : :
45 : 0 : if (_read < 0) {
46 : 0 : switch (errno) {
47 : : case EINTR:
48 : : case ENOMEM:
49 : 0 : done = 0;
50 : 0 : break;
51 : : case (EAGAIN|EWOULDBLOCK):
52 : 0 : done = -1;
53 : 0 : break;
54 : : default:
55 : 0 : done = -2;
56 : 0 : break;
57 : : }
58 : 0 : } else if (_read == 0) {
59 : 0 : done = -2;
60 : : } else {
61 : 0 : done = _read;
62 : : }
63 : :
64 : 0 : break;
65 : :
66 : : case STREAM_SSL:
67 : 0 : done = SSL_read((this->handle).ssl, buf, count);
68 : :
69 : 0 : if (0 == done) {
70 : 0 : done = -2;
71 : 0 : } else if (0 > done) {
72 : 0 : switch (SSL_get_error((this->handle).ssl, done)) {
73 : : case SSL_ERROR_SYSCALL:
74 : : {
75 : 0 : switch (errno) {
76 : : case EINTR:
77 : : case ENOBUFS:
78 : : case ENOMEM:
79 : 0 : done = 0;
80 : 0 : break;
81 : : case (EAGAIN|EWOULDBLOCK):
82 : 0 : done = -1;
83 : 0 : break;
84 : : default:
85 : 0 : done = -1;
86 : 0 : break;
87 : : }
88 : : }
89 : 0 : break;
90 : :
91 : : case SSL_ERROR_SSL:
92 : : {
93 : : unsigned long err;
94 : :
95 : 0 : while (0 != (err = ERR_get_error())) {
96 : 0 : loggerLog(
97 : : logger,
98 : : LOGGER_DEBUG,
99 : 0 : ERR_error_string(err, NULL));
100 : : }
101 : : }
102 : : // DROP THROUGH
103 : :
104 : : case SSL_ERROR_ZERO_RETURN:
105 : 0 : done = -2;
106 : 0 : break;
107 : : }
108 : : }
109 : :
110 : 0 : break;
111 : :
112 : : default:
113 : 0 : done = -2;
114 : 0 : break;
115 : : }
116 : :
117 : 0 : return done;
118 : : }
119 : :
120 : : // vim: set ts=4 sw=4:
|