echoping/SRC/readline.c
2003-11-05 12:14:01 +00:00

225 lines
4.2 KiB
C

/*
* Read a line from a descriptor with fgets
*
* $Id$
*
*/
#include "echoping.h"
int
readline (fs, ptr, maxlen, ln)
FILE *fs;
char *ptr;
int maxlen;
unsigned short ln;
{
int n = 1;
char *rc;
int r;
/* Reading with fgets or fread instead of read
one-character-at-a-time is more than ten times faster, on a local
server. */
if (ln)
{
rc = fgets (ptr, maxlen + 1, fs);
if (rc == NULL)
{
return (-1);
}
n = strlen (rc);
return n;
}
else
{
while (n < maxlen)
{
r = fread (ptr, 1, maxlen, fs);
if (r == 0)
{
if (timeout_flag)
return n;
if (n == 1)
return (0); /* EOF, no data read */
else
break; /* EOF, some data was read */
}
n = n + r;
}
}
return (n);
}
#ifdef OPENSSL
char SSL_buffer[MAXTOREAD];
int buf_ptr;
int buf_end;
int
SSL_readline (sslh, ptr, maxlen, ln)
SSL *sslh;
char *ptr;
int maxlen;
unsigned short ln;
{
int rc = 0;
int n = 0;
int i, oi;
if (ln)
{
/* Empty buffer */
if (buf_end == 0)
{
rc = SSL_read (sslh, SSL_buffer, maxlen);
if (rc == -1)
return rc;
buf_end = rc;
buf_ptr = 0;
}
/* No more data in the buffer */
else if (buf_ptr == buf_end)
{
buf_ptr = 0;
rc = SSL_read (sslh, SSL_buffer, maxlen);
if (rc == -1)
return rc;
buf_end = rc;
}
else if (SSL_buffer[buf_end] != '\n')
{
/* We have a probleme here is the first SSL_read sent back
a text not finished by a \n. See www.SSL.de for an
example. We get more data. See bug #230384 */
rc = SSL_read (sslh, SSL_buffer + buf_end, maxlen);
if (rc == -1)
return rc;
buf_end = buf_end + rc;
}
for (oi = buf_ptr, i = buf_ptr;
i <= buf_end && SSL_buffer[i] != '\n'; i++)
{
*ptr++ = SSL_buffer[i];
buf_ptr++;
}
if (SSL_buffer[i] == '\n')
buf_ptr++;
*ptr = '\0';
/* if (ln)
printf ("SSL_readline returns %d (%s)\n", i - oi, SSL_buffer); */
return (i - oi);
}
else
{
/* OpenSSL reads at most 4096 characters */
rc = 1; /* Just to avoid exiting too soon */
while (n < maxlen && rc != 0)
{
if ((buf_end == 0) || (buf_ptr > buf_end))
{
rc = SSL_read (sslh, ptr, maxlen);
buf_end = 0;
buf_ptr = 0;
}
else
{
for (i = buf_ptr; i < maxlen && i <= buf_end; i++)
{
*ptr++ = SSL_buffer[i];
rc++;
}
buf_ptr = i;
}
n = n + rc;
}
return n;
}
}
#endif
#ifdef GNUTLS
char TLS_buffer[MAXTOREAD];
int buf_ptr;
int buf_end;
int
TLS_readline (session, ptr, maxlen, ln)
gnutls_session session;
char *ptr;
int maxlen;
unsigned short ln;
{
int rc = 0;
int n = 0;
int i, oi;
if (ln)
{
/* Empty buffer */
if (buf_end == 0)
{
rc = gnutls_record_recv (session, TLS_buffer, maxlen);
if (rc == -1)
return rc;
buf_end = rc;
buf_ptr = 0;
}
/* No more data in the buffer */
else if (buf_ptr == buf_end)
{
buf_ptr = 0;
rc = gnutls_record_recv (session, TLS_buffer, maxlen);
if (rc == -1)
return rc;
buf_end = rc;
}
else if (TLS_buffer[buf_end] != '\n')
{
rc = gnutls_record_recv (session, TLS_buffer + buf_end, maxlen);
if (rc == -1)
return rc;
buf_end = buf_end + rc;
}
for (oi = buf_ptr, i = buf_ptr;
i <= buf_end && TLS_buffer[i] != '\n'; i++)
{
*ptr++ = TLS_buffer[i];
buf_ptr++;
}
if (TLS_buffer[i] == '\n')
buf_ptr++;
*ptr = '\0';
/* printf ("DEBUG: TLS_readline returns %d (%s)\n", i - oi, TLS_buffer); */
return (i - oi);
}
else
{
rc = 1; /* Just to avoid exiting too soon */
while (n < maxlen && rc > 0)
{
if ((buf_end == 0) || (buf_ptr > buf_end))
{
rc = gnutls_record_recv (session, ptr, maxlen);
buf_end = 0;
buf_ptr = 0;
}
else
{
for (i = buf_ptr; i < maxlen && i <= buf_end; i++)
{
*ptr++ = TLS_buffer[i];
rc++;
/* printf ("DEBUG: Now %d chars read\n", rc); */
}
buf_ptr = i;
}
if (rc > 0)
n = n + rc;
/* printf ("DEBUG: Now %d chars to send\n", n); */
}
return n;
}
}
#endif