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