00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _WIN32
00020 #include <unistd.h>
00021 #include <sys/uio.h>
00022 #include <sys/types.h>
00023 #include <sys/socket.h>
00024 #else
00025
00026 #ifdef _MSC_VER
00027
00028
00029
00030
00031
00032 #pragma warning( disable : 4115 4127 4514 )
00033 #endif
00034
00035 #include <io.h>
00036 #endif
00037 #include <errno.h>
00038 #include <signal.h>
00039 #include <stdio.h>
00040 #include "utils.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef _WIN32
00053 typedef void sigfunc(int);
00054
00055 sigfunc *sig_catch(int sig, void (*f) (int))
00056 {
00057 struct sigaction act, oact;
00058 act.sa_handler = f;
00059 act.sa_flags = 0;
00060 sigemptyset(&act.sa_mask);
00061 sigaction(sig, &act, &oact);
00062 return oact.sa_handler;
00063 }
00064
00065 static void catch_alrm(int x)
00066 {
00067 UNUSED_VARIABLE(x);
00068 }
00069 #endif
00070
00071 int timeout_connect (int sockfd, const struct sockaddr *serv_addr, size_t addrlen)
00072 {
00073 int ret;
00074
00075 #ifndef _WIN32
00076 sigfunc* sig;
00077
00078 sig = sig_catch(SIGALRM, catch_alrm);
00079 if (libspamc_timeout > 0) {
00080 alarm(libspamc_timeout);
00081 }
00082 #endif
00083
00084 ret = connect(sockfd, serv_addr, addrlen);
00085
00086 #ifndef _WIN32
00087 if (libspamc_timeout > 0) {
00088 alarm(0);
00089 }
00090
00091
00092 sig_catch(SIGALRM, sig);
00093 #endif
00094
00095 return ret;
00096 }
00097
00098 int fd_timeout_read(int fd, char fdflag, void *buf, size_t nbytes)
00099 {
00100 int nred;
00101 int origerr;
00102 #ifndef _WIN32
00103 sigfunc *sig;
00104
00105 sig = sig_catch(SIGALRM, catch_alrm);
00106 if (libspamc_timeout > 0) {
00107 alarm(libspamc_timeout);
00108 }
00109 #endif
00110
00111 do {
00112 if (fdflag) {
00113 nred = (int)read(fd, buf, nbytes);
00114 origerr = errno;
00115 }
00116 else {
00117 nred = (int)recv(fd, buf, nbytes, 0);
00118 #ifndef _WIN32
00119 origerr = errno;
00120 #else
00121 origerr = WSAGetLastError();
00122 #endif
00123 }
00124 } while (nred < 0 && origerr == EWOULDBLOCK);
00125
00126 #ifndef _WIN32
00127 if (nred < 0 && origerr == EINTR)
00128 errno = ETIMEDOUT;
00129
00130 if (libspamc_timeout > 0) {
00131 alarm(0);
00132 }
00133
00134
00135 sig_catch(SIGALRM, sig);
00136 #endif
00137
00138 return nred;
00139 }
00140
00141 int ssl_timeout_read(SSL * ssl, void *buf, int nbytes)
00142 {
00143 int nred;
00144
00145 #ifndef _WIN32
00146 sigfunc *sig;
00147
00148 sig = sig_catch(SIGALRM, catch_alrm);
00149 if (libspamc_timeout > 0) {
00150 alarm(libspamc_timeout);
00151 }
00152 #endif
00153
00154 do {
00155
00156 #ifdef SPAMC_SSL
00157 nred = SSL_read(ssl, buf, nbytes);
00158 #else
00159 UNUSED_VARIABLE(ssl);
00160 UNUSED_VARIABLE(buf);
00161 UNUSED_VARIABLE(nbytes);
00162 nred = 0;
00163 #endif
00164
00165 } while (nred < 0 && errno == EWOULDBLOCK);
00166
00167 #ifndef _WIN32
00168 if (nred < 0 && errno == EINTR)
00169 errno = ETIMEDOUT;
00170
00171 if (libspamc_timeout > 0) {
00172 alarm(0);
00173 }
00174
00175
00176 sig_catch(SIGALRM, sig);
00177 #endif
00178
00179 return nred;
00180 }
00181
00182
00183
00184 int full_read(int fd, char fdflag, void *vbuf, int min, int len)
00185 {
00186 unsigned char *buf = (unsigned char *) vbuf;
00187 int total;
00188 int thistime;
00189
00190 for (total = 0; total < min;) {
00191 thistime = fd_timeout_read(fd, fdflag, buf + total, len - total);
00192
00193 if (thistime < 0) {
00194 if (total >= min) {
00195
00196
00197 return total;
00198 } else {
00199 return -1;
00200 }
00201 }
00202 else if (thistime == 0) {
00203
00204
00205 return total;
00206 }
00207
00208 total += thistime;
00209 }
00210 return total;
00211 }
00212
00213 int full_read_ssl(SSL * ssl, unsigned char *buf, int min, int len)
00214 {
00215 int total;
00216 int thistime;
00217
00218 for (total = 0; total < min;) {
00219 thistime = ssl_timeout_read(ssl, buf + total, len - total);
00220
00221 if (thistime < 0) {
00222 if (total >= min) {
00223
00224
00225 return total;
00226 } else {
00227 return -1;
00228 }
00229 }
00230 else if (thistime == 0) {
00231
00232
00233 return total;
00234 }
00235
00236 total += thistime;
00237 }
00238 return total;
00239 }
00240
00241 int full_write(int fd, char fdflag, const void *vbuf, int len)
00242 {
00243 const char *buf = (const char *) vbuf;
00244 int total;
00245 int thistime;
00246 int origerr;
00247
00248 for (total = 0; total < len;) {
00249 if (fdflag) {
00250 thistime = write(fd, buf + total, len - total);
00251 origerr = errno;
00252 }
00253 else {
00254 thistime = send(fd, buf + total, len - total, 0);
00255 #ifndef _WIN32
00256 origerr = errno;
00257 #else
00258 origerr = WSAGetLastError();
00259 #endif
00260 }
00261 if (thistime < 0) {
00262 if (EINTR == origerr || EWOULDBLOCK == origerr)
00263 continue;
00264 return thistime;
00265 }
00266 total += thistime;
00267 }
00268 return total;
00269 }