#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "rw.h"
#include "ssl.h"
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
extern unsigned int timeout;
/* two wrapper functions making reading and writing transparent */
static ssize_t generic_read(int fd, void * buf, size_t count) {
fd_set rs;
struct timeval to = { timeout, 0 };
FD_ZERO(&rs);
if (buf == NULL)
return 0;
FD_SET(fd,&rs);
select(fd+1,&rs,NULL,NULL,&to);
if (!FD_ISSET(fd,&rs)) {
write_line(fd,"-ERR read() timed out.\r\n");
syslog(LOG_ERR,"read() timed out.");
exit(EXIT_FAILURE);
}
#if HAVE_LIBSSL
if (use_ssl()) {
return SSL_read(get_ssl_handle(),buf,count);
}
#endif
return read(fd,buf,count);
}
static ssize_t generic_write(int fd, void * buf, size_t count) {
fd_set ws;
struct timeval to = { timeout, 0 };
FD_ZERO(&ws);
if (buf == NULL)
return 0;
FD_SET(fd,&ws);
select(fd+1,NULL,&ws,NULL,&to);
if (!FD_ISSET(fd,&ws)) {
syslog(LOG_ERR,"write() timed out.");
exit(EXIT_FAILURE);
}
#if HAVE_LIBSSL
if (use_ssl()) {
return SSL_write(get_ssl_handle(),buf,count);
}
#endif
return write(fd,buf,count);
}
int write_line(int fd, char * line) {
size_t n;
size_t nleft;
ssize_t nwritten;
char * ptr;
if (line == NULL) return 0;
n = strlen(line);
ptr = line;
nleft = n;
while (nleft > 0) {
if ((nwritten = generic_write(fd, ptr, nleft)) <= 0) {
if (errno!= EINTR) {
syslog(LOG_ERR,"%s: %s","write failed - aborting",strerror(errno));
exit(EXIT_FAILURE);
}
nwritten = 0;
}
nleft -= nwritten;
ptr += nwritten;
}
return n;
}
static ssize_t my_read(int fd, char * ptr) {
static int read_cnt = 0;
static char * read_ptr;
static char read_buf[MAXLINE];
if (ptr==NULL)
return 0;
if (read_cnt <= 0) {
again:
if ((read_cnt = generic_read(fd,read_buf,sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again;
return -1;
} else if (read_cnt == 0)
return 0;
read_ptr = read_buf;
}
read_cnt--;
*ptr = *read_ptr++;
return 1;
}
static ssize_t my_readline(int fd, char * vptr, size_t maxlen) {
int n, rc;
char c, * ptr;
if (vptr==NULL)
return 0;
ptr = vptr;
for (n = 1; n < maxlen; n++) {
if ((rc = my_read(fd,&c)) == 1) {
*ptr++ = c;
if (c=='\n')
break;
} else if (rc==0) {
if (n==1) {
*ptr = '\0';
return 0;
} else
break;
} else
return -1;
}
*ptr = '\0';
/* truncate lines that are too long */
if (strlen(vptr)>0 && vptr[strlen(vptr)-1]!='\n') {
char c;
int rc;
rc = generic_read(fd,&c,sizeof(c));
while (rc==sizeof(c) && c!='\n') {
rc = generic_read(fd,&c,sizeof(c));
}
}
return n;
}
ssize_t read_line(int fd, char * ptr, size_t maxlen) {
ssize_t n;
if (ptr==NULL)
return 0;
if ((n = my_readline(fd,ptr,maxlen)) < 0) {
syslog(LOG_ERR,"%s: %s","read failed - aborting",strerror(errno));
exit(EXIT_FAILURE);
}
return n;
}
syntax highlighted by Code2HTML, v. 0.9.1