masqmail-0.2

view src/readsock.c @ 3:8c55886cacd8

man pages will be maintained in troff now
author meillo@marmaro.de
date Fri, 26 Sep 2008 21:40:10 +0200
parents
children 26e34ae9a3e3
line source
1 /* MasqMail
2 Copyright (C) 2000 Oliver Kurth
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
19 /*#include "masqmail.h"*/
20 #include <signal.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <setjmp.h>
24 #include <unistd.h>
25 #include <ctype.h>
26 #include "readsock.h"
28 jmp_buf jmp_timeout;
30 static
31 void sig_timeout_handler(int sig)
32 {
33 longjmp(jmp_timeout, 1);
34 }
36 static struct sigaction old_sa_alrm;
38 static
39 void alarm_on(int timeout)
40 {
41 struct sigaction sa;
43 sa.sa_handler = sig_timeout_handler;
44 sigemptyset(&(sa.sa_mask));
45 sa.sa_flags = 0;
46 sigaction(SIGALRM, &sa, &old_sa_alrm);
48 if(timeout > 0)
49 alarm(timeout);
50 }
52 static
53 void alarm_off()
54 {
55 alarm(0);
57 sigaction(SIGALRM, &old_sa_alrm, NULL);
58 }
60 static
61 void _read_chug(FILE *in)
62 {
63 int c = 0;
65 c = fgetc(in);
66 while(isspace(c) && (c != EOF)) c = fgetc(in);
67 ungetc(c, in);
68 }
70 static
71 int _read_line(FILE *in, char *buf, int buf_len, int timeout)
72 {
73 int p = 0;
74 int c = 0;
76 c = fgetc(in);
77 while((c != '\n') && (c != EOF) && (p < buf_len-1)){
78 buf[p++] = c;
79 c = fgetc(in);
80 }
82 buf[p] = 0;
84 if(c == EOF)
85 return -1;
86 else if(p >= buf_len){
87 ungetc(c, in);
88 return -2;
89 }
91 buf[p++] = c; /* \n */
92 buf[p] = 0;
94 return p;
95 }
97 int read_sockline(FILE *in, char *buf, int buf_len, int timeout, unsigned int flags)
98 {
99 int p = 0;
101 if(setjmp(jmp_timeout) != 0){
102 alarm_off();
103 return -3;
104 }
106 alarm_on(timeout);
108 /* strip leading spaces */
109 if(flags & READSOCKL_CHUG){
110 _read_chug(in);
111 }
113 p = _read_line(in, buf, buf_len, timeout);
115 alarm_off();
117 if(p > 1){
118 /* here we are sure that buf[p-1] == '\n' */
119 if(flags & READSOCKL_CVT_CRLF){
120 if((buf[p-2] == '\r') && (buf[p-1] == '\n')){
121 buf[p-2] = '\n';
122 buf[p-1] = 0;
123 p--;
124 }
125 }
126 }
127 return p;
128 }
130 int read_sockline1(FILE *in, char **pbuf, int *buf_len, int timeout, unsigned int flags)
131 {
132 int p = 0, size = *buf_len;
133 char *buf;
135 if(setjmp(jmp_timeout) != 0){
136 alarm_off();
137 return -3;
138 }
140 alarm_on(timeout);
142 /* strip leading spaces */
143 if(flags & READSOCKL_CHUG){
144 _read_chug(in);
145 }
147 if(!*pbuf) *pbuf = malloc(size);
148 buf = *pbuf;
150 while(1){
151 int pp;
153 pp = _read_line(in, buf, size, timeout);
154 if(pp == -2){
155 *pbuf = realloc(*pbuf, *buf_len + size);
156 buf = *pbuf + *buf_len;
157 *buf_len += size;
158 p += size;
159 }
160 else{
161 if(pp > 0) p += pp;
162 else p = pp;
163 break;
164 }
165 }
167 alarm_off();
169 if(p > 1){
170 buf = *pbuf;
171 /* here we are sure that buf[p-1] == '\n' */
172 if(flags & READSOCKL_CVT_CRLF){
173 if((buf[p-2] == '\r') && (buf[p-1] == '\n')){
174 buf[p-2] = '\n';
175 buf[p-1] = 0;
176 p--;
177 }
178 }
179 }
180 return p;
181 }