00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "bioStreamBuf.h"
00020 #include "config_downloader.h"
00021
00022 #ifdef HAVE_SSL
00023
00024 #ifdef REPORT_OPENSSL_ERRORS
00025 #include <openssl/err.h>
00026 #endif
00027
00028 #ifndef HAVE_STREAMSIZE
00029
00030 typedef int streamsize;
00031 #endif
00032
00033
00034
00035
00036
00037
00038 BioStreamBuf::
00039 BioStreamBuf() {
00040 _is_closed = false;
00041
00042 #ifdef HAVE_IOSTREAM
00043 char *buf = new char[8192];
00044 char *ebuf = buf + 8192;
00045 char *mbuf = buf + 4096;
00046 setg(buf, mbuf, mbuf);
00047 setp(mbuf, ebuf);
00048
00049 #else
00050 allocate();
00051
00052
00053 char *b = base();
00054 char *t = ebuf();
00055 char *m = b + (t - b) / 2;
00056 setg(b, m, m);
00057 setp(b, m);
00058 #endif
00059 }
00060
00061
00062
00063
00064
00065
00066 BioStreamBuf::
00067 ~BioStreamBuf() {
00068 close();
00069 }
00070
00071
00072
00073
00074
00075
00076 void BioStreamBuf::
00077 open(BioPtr *source) {
00078 _source = source;
00079 }
00080
00081
00082
00083
00084
00085
00086 void BioStreamBuf::
00087 close() {
00088 sync();
00089 _source.clear();
00090 }
00091
00092
00093
00094
00095
00096
00097
00098 int BioStreamBuf::
00099 overflow(int ch) {
00100 size_t n = pptr() - pbase();
00101 if (n != 0) {
00102 size_t num_wrote = write_chars(pbase(), n);
00103 pbump(-(int)n);
00104 if (num_wrote != n) {
00105 return EOF;
00106 }
00107 }
00108
00109 if (ch != EOF) {
00110
00111 *pptr() = ch;
00112 pbump(1);
00113 }
00114
00115 return 0;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 int BioStreamBuf::
00125 sync() {
00126
00127
00128
00129
00130
00131 size_t n = pptr() - pbase();
00132 size_t num_wrote = write_chars(pbase(), n);
00133 pbump(-(int)n);
00134 if (num_wrote != n) {
00135 return EOF;
00136 }
00137
00138 return 0;
00139 }
00140
00141
00142
00143
00144
00145
00146
00147 int BioStreamBuf::
00148 underflow() {
00149
00150 if (gptr() >= egptr()) {
00151 size_t buffer_size = egptr() - eback();
00152 gbump(-(int)buffer_size);
00153
00154 size_t num_bytes = buffer_size;
00155
00156
00157
00158 int read_count = BIO_read(*_source, gptr(), buffer_size);
00159
00160 if (read_count != (int)num_bytes) {
00161
00162 if (read_count <= 0) {
00163 _is_closed = !BIO_should_retry(*_source);
00164 if (_is_closed) {
00165 downloader_cat.info()
00166 << "Lost connection to "
00167 << _source->get_server_name() << ":"
00168 << _source->get_port() << " (" << read_count << ").\n";
00169 #ifdef REPORT_OPENSSL_ERRORS
00170 ERR_print_errors_fp(stderr);
00171 #endif
00172 }
00173 gbump(num_bytes);
00174 return EOF;
00175 }
00176
00177
00178 nassertr(read_count < (int)num_bytes, EOF);
00179 size_t delta = (int)num_bytes - read_count;
00180 memmove(gptr() + delta, gptr(), read_count);
00181 gbump(delta);
00182 }
00183 }
00184
00185 return (unsigned char)*gptr();
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 size_t BioStreamBuf::
00196 write_chars(const char *start, size_t length) {
00197 size_t wrote_so_far = 0;
00198
00199 int write_count = BIO_write(*_source, start, length);
00200 while (write_count != (int)(length - wrote_so_far)) {
00201 if (write_count <= 0) {
00202 _is_closed = !BIO_should_retry(*_source);
00203 if (_is_closed) {
00204 return wrote_so_far;
00205 }
00206
00207
00208
00209 int fd = -1;
00210 BIO_get_fd(*_source, &fd);
00211 if (fd < 0) {
00212 downloader_cat.warning()
00213 << "socket BIO has no file descriptor.\n";
00214 } else {
00215 downloader_cat.spam()
00216 << "waiting to write to BIO.\n";
00217 fd_set wset;
00218 FD_ZERO(&wset);
00219 FD_SET(fd, &wset);
00220 select(fd + 1, NULL, &wset, NULL, NULL);
00221 }
00222
00223 } else {
00224
00225 wrote_so_far += write_count;
00226 }
00227
00228
00229 write_count = BIO_write(*_source, start + wrote_so_far, length - wrote_so_far);
00230 }
00231
00232 return length;
00233 }
00234
00235 #endif // HAVE_SSL