meillo@0: /* MasqMail meillo@0: Copyright (C) 2000 Oliver Kurth meillo@0: meillo@0: This program is free software; you can redistribute it and/or modify meillo@0: it under the terms of the GNU General Public License as published by meillo@0: the Free Software Foundation; either version 2 of the License, or meillo@0: (at your option) any later version. meillo@0: meillo@0: This program is distributed in the hope that it will be useful, meillo@0: but WITHOUT ANY WARRANTY; without even the implied warranty of meillo@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the meillo@0: GNU General Public License for more details. meillo@0: meillo@0: You should have received a copy of the GNU General Public License meillo@0: along with this program; if not, write to the Free Software meillo@0: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. meillo@0: */ meillo@0: meillo@0: /*#include "masqmail.h"*/ meillo@0: #include meillo@0: #include meillo@0: #include meillo@0: #include meillo@0: #include meillo@0: #include meillo@0: #include "readsock.h" meillo@0: meillo@0: jmp_buf jmp_timeout; meillo@0: meillo@0: static meillo@0: void sig_timeout_handler(int sig) meillo@0: { meillo@0: longjmp(jmp_timeout, 1); meillo@0: } meillo@0: meillo@0: static struct sigaction old_sa_alrm; meillo@0: meillo@0: static meillo@0: void alarm_on(int timeout) meillo@0: { meillo@0: struct sigaction sa; meillo@0: meillo@0: sa.sa_handler = sig_timeout_handler; meillo@0: sigemptyset(&(sa.sa_mask)); meillo@0: sa.sa_flags = 0; meillo@0: sigaction(SIGALRM, &sa, &old_sa_alrm); meillo@0: meillo@0: if(timeout > 0) meillo@0: alarm(timeout); meillo@0: } meillo@0: meillo@0: static meillo@0: void alarm_off() meillo@0: { meillo@0: alarm(0); meillo@0: meillo@0: sigaction(SIGALRM, &old_sa_alrm, NULL); meillo@0: } meillo@0: meillo@0: static meillo@0: void _read_chug(FILE *in) meillo@0: { meillo@0: int c = 0; meillo@0: meillo@0: c = fgetc(in); meillo@0: while(isspace(c) && (c != EOF)) c = fgetc(in); meillo@0: ungetc(c, in); meillo@0: } meillo@0: meillo@0: static meillo@0: int _read_line(FILE *in, char *buf, int buf_len, int timeout) meillo@0: { meillo@0: int p = 0; meillo@0: int c = 0; meillo@0: meillo@0: c = fgetc(in); meillo@0: while((c != '\n') && (c != EOF) && (p < buf_len-1)){ meillo@0: buf[p++] = c; meillo@0: c = fgetc(in); meillo@0: } meillo@0: meillo@0: buf[p] = 0; meillo@0: meillo@0: if(c == EOF) meillo@0: return -1; meillo@0: else if(p >= buf_len){ meillo@0: ungetc(c, in); meillo@0: return -2; meillo@0: } meillo@0: meillo@0: buf[p++] = c; /* \n */ meillo@0: buf[p] = 0; meillo@0: meillo@0: return p; meillo@0: } meillo@0: meillo@0: int read_sockline(FILE *in, char *buf, int buf_len, int timeout, unsigned int flags) meillo@0: { meillo@0: int p = 0; meillo@0: meillo@0: if(setjmp(jmp_timeout) != 0){ meillo@0: alarm_off(); meillo@0: return -3; meillo@0: } meillo@0: meillo@0: alarm_on(timeout); meillo@0: meillo@0: /* strip leading spaces */ meillo@0: if(flags & READSOCKL_CHUG){ meillo@0: _read_chug(in); meillo@0: } meillo@0: meillo@0: p = _read_line(in, buf, buf_len, timeout); meillo@0: meillo@0: alarm_off(); meillo@0: meillo@0: if(p > 1){ meillo@0: /* here we are sure that buf[p-1] == '\n' */ meillo@0: if(flags & READSOCKL_CVT_CRLF){ meillo@0: if((buf[p-2] == '\r') && (buf[p-1] == '\n')){ meillo@0: buf[p-2] = '\n'; meillo@0: buf[p-1] = 0; meillo@0: p--; meillo@0: } meillo@0: } meillo@0: } meillo@0: return p; meillo@0: } meillo@0: meillo@0: int read_sockline1(FILE *in, char **pbuf, int *buf_len, int timeout, unsigned int flags) meillo@0: { meillo@0: int p = 0, size = *buf_len; meillo@0: char *buf; meillo@0: meillo@0: if(setjmp(jmp_timeout) != 0){ meillo@0: alarm_off(); meillo@0: return -3; meillo@0: } meillo@0: meillo@0: alarm_on(timeout); meillo@0: meillo@0: /* strip leading spaces */ meillo@0: if(flags & READSOCKL_CHUG){ meillo@0: _read_chug(in); meillo@0: } meillo@0: meillo@0: if(!*pbuf) *pbuf = malloc(size); meillo@0: buf = *pbuf; meillo@0: meillo@0: while(1){ meillo@0: int pp; meillo@0: meillo@0: pp = _read_line(in, buf, size, timeout); meillo@0: if(pp == -2){ meillo@0: *pbuf = realloc(*pbuf, *buf_len + size); meillo@0: buf = *pbuf + *buf_len; meillo@0: *buf_len += size; meillo@0: p += size; meillo@0: } meillo@0: else{ meillo@0: if(pp > 0) p += pp; meillo@0: else p = pp; meillo@0: break; meillo@0: } meillo@0: } meillo@0: meillo@0: alarm_off(); meillo@0: meillo@0: if(p > 1){ meillo@0: buf = *pbuf; meillo@0: /* here we are sure that buf[p-1] == '\n' */ meillo@0: if(flags & READSOCKL_CVT_CRLF){ meillo@0: if((buf[p-2] == '\r') && (buf[p-1] == '\n')){ meillo@0: buf[p-2] = '\n'; meillo@0: buf[p-1] = 0; meillo@0: p--; meillo@0: } meillo@0: } meillo@0: } meillo@0: return p; meillo@0: } meillo@0: