#if HAVE_CONFIG_H # include "config.h" #endif #include "rw.h" #include "ssl.h" #include #include #include #include #include #include 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; }