diff src/readsock.c @ 0:08114f7dcc23 0.2.21

this is masqmail-0.2.21 from oliver kurth
author meillo@marmaro.de
date Fri, 26 Sep 2008 17:05:23 +0200
parents
children 26e34ae9a3e3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/readsock.c	Fri Sep 26 17:05:23 2008 +0200
@@ -0,0 +1,182 @@
+/*  MasqMail
+    Copyright (C) 2000 Oliver Kurth
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*#include "masqmail.h"*/
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <unistd.h>
+#include <ctype.h>
+#include "readsock.h"
+
+jmp_buf jmp_timeout;
+
+static
+void sig_timeout_handler(int sig)
+{
+  longjmp(jmp_timeout, 1);
+}
+
+static struct sigaction old_sa_alrm;
+
+static
+void alarm_on(int timeout)
+{
+  struct sigaction sa;
+
+  sa.sa_handler = sig_timeout_handler;
+  sigemptyset(&(sa.sa_mask));
+  sa.sa_flags = 0;
+  sigaction(SIGALRM, &sa, &old_sa_alrm);
+
+  if(timeout > 0)
+    alarm(timeout);
+}
+
+static
+void alarm_off()
+{
+  alarm(0);
+
+  sigaction(SIGALRM, &old_sa_alrm, NULL);
+}
+
+static
+void _read_chug(FILE *in)
+{
+  int c = 0;
+
+  c = fgetc(in);
+  while(isspace(c) && (c != EOF)) c = fgetc(in);
+  ungetc(c, in);
+}
+
+static
+int _read_line(FILE *in, char *buf, int buf_len, int timeout)
+{
+  int p = 0;
+  int c = 0;
+
+  c = fgetc(in);
+  while((c != '\n') && (c != EOF) && (p < buf_len-1)){
+    buf[p++] = c;
+    c = fgetc(in);
+  }
+
+  buf[p] = 0;
+
+  if(c == EOF)
+    return -1;
+  else if(p >= buf_len){
+    ungetc(c, in);
+    return -2;
+  }
+
+  buf[p++] = c; /* \n */
+  buf[p] = 0;
+
+  return p;
+}
+
+int read_sockline(FILE *in, char *buf, int buf_len, int timeout, unsigned int flags)
+{
+  int p = 0;
+
+  if(setjmp(jmp_timeout) != 0){
+    alarm_off();
+    return -3;
+  }
+
+  alarm_on(timeout);
+
+  /* strip leading spaces */
+  if(flags & READSOCKL_CHUG){
+    _read_chug(in);
+  }
+
+  p = _read_line(in, buf, buf_len, timeout);
+
+  alarm_off();
+
+  if(p > 1){
+    /* here we are sure that buf[p-1] == '\n' */
+    if(flags & READSOCKL_CVT_CRLF){
+      if((buf[p-2] == '\r') && (buf[p-1] == '\n')){
+	buf[p-2] = '\n';
+	buf[p-1] = 0;
+	p--;
+      }
+    }
+  }
+  return p;
+}
+
+int read_sockline1(FILE *in, char **pbuf, int *buf_len, int timeout, unsigned int flags)
+{
+  int p = 0, size = *buf_len;
+  char *buf;
+
+  if(setjmp(jmp_timeout) != 0){
+    alarm_off();
+    return -3;
+  }
+
+  alarm_on(timeout);
+
+  /* strip leading spaces */
+  if(flags & READSOCKL_CHUG){
+    _read_chug(in);
+  }
+
+  if(!*pbuf) *pbuf = malloc(size);
+  buf = *pbuf;
+  
+  while(1){
+    int pp;
+
+    pp = _read_line(in, buf, size, timeout);
+    if(pp == -2){
+      *pbuf = realloc(*pbuf, *buf_len + size);
+      buf = *pbuf + *buf_len;
+      *buf_len += size;
+      p += size;
+    }
+    else{
+      if(pp > 0) p += pp;
+      else p = pp;
+      break;
+    }
+  }
+
+  alarm_off();
+
+  if(p > 1){
+    buf = *pbuf;
+    /* here we are sure that buf[p-1] == '\n' */
+    if(flags & READSOCKL_CVT_CRLF){
+      if((buf[p-2] == '\r') && (buf[p-1] == '\n')){
+	buf[p-2] = '\n';
+	buf[p-1] = 0;
+	p--;
+      }
+    }
+  }
+  return p;
+}
+