masqmail-0.2

annotate 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
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