masqmail

view src/readsock.c @ 432:ddc05e12e307

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