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