masqmail-0.2

annotate src/readsock.c @ 27:3654c502a4df

g_malloc terminates the program on failure automatically
author meillo@marmaro.de
date Thu, 06 May 2010 11:50:40 +0200
parents f671821d8222
children
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 <signal.h>
meillo@0 20 #include <stdio.h>
meillo@0 21 #include <stdlib.h>
meillo@0 22 #include <setjmp.h>
meillo@0 23 #include <unistd.h>
meillo@0 24 #include <ctype.h>
meillo@15 25
meillo@0 26 #include "readsock.h"
meillo@15 27 /*#include "masqmail.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@10 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@10 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@10 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@10 134 read_sockline1(FILE * in, char **pbuf, int *buf_len, int timeout, unsigned int flags)
meillo@0 135 {
meillo@10 136 int p = 0, size = *buf_len;
meillo@10 137 char *buf;
meillo@0 138
meillo@10 139 if (setjmp(jmp_timeout) != 0) {
meillo@10 140 alarm_off();
meillo@10 141 return -3;
meillo@10 142 }
meillo@0 143
meillo@10 144 alarm_on(timeout);
meillo@0 145
meillo@10 146 /* strip leading spaces */
meillo@10 147 if (flags & READSOCKL_CHUG) {
meillo@10 148 _read_chug(in);
meillo@10 149 }
meillo@0 150
meillo@10 151 if (!*pbuf)
meillo@27 152 *pbuf = g_malloc(size);
meillo@10 153 buf = *pbuf;
meillo@0 154
meillo@10 155 while (1) {
meillo@10 156 int pp;
meillo@0 157
meillo@10 158 pp = _read_line(in, buf, size, timeout);
meillo@10 159 if (pp == -2) {
meillo@10 160 *pbuf = realloc(*pbuf, *buf_len + size);
meillo@10 161 buf = *pbuf + *buf_len;
meillo@10 162 *buf_len += size;
meillo@10 163 p += size;
meillo@10 164 } else {
meillo@10 165 if (pp > 0)
meillo@10 166 p += pp;
meillo@10 167 else
meillo@10 168 p = pp;
meillo@10 169 break;
meillo@10 170 }
meillo@10 171 }
meillo@0 172
meillo@10 173 alarm_off();
meillo@10 174
meillo@10 175 if (p > 1) {
meillo@10 176 buf = *pbuf;
meillo@10 177 /* here we are sure that buf[p-1] == '\n' */
meillo@10 178 if (flags & READSOCKL_CVT_CRLF) {
meillo@10 179 if ((buf[p - 2] == '\r') && (buf[p - 1] == '\n')) {
meillo@10 180 buf[p - 2] = '\n';
meillo@15 181 buf[p - 1] = '\0';
meillo@10 182 p--;
meillo@10 183 }
meillo@10 184 }
meillo@10 185 }
meillo@10 186 return p;
meillo@0 187 }