100 lines
2.0 KiB
C
100 lines
2.0 KiB
C
/*
|
|
* Part of Very Secure FTPd
|
|
* Licence: GPL v2
|
|
* Author: Chris Evans
|
|
* ascii.c
|
|
*
|
|
* Routines to handle ASCII mode tranfers. Yuk.
|
|
*/
|
|
|
|
#include "ascii.h"
|
|
|
|
struct ascii_to_bin_ret
|
|
vsf_ascii_ascii_to_bin(char* p_buf, unsigned int in_len, int prev_cr)
|
|
{
|
|
/* Task: translate all \r\n into plain \n. A plain \r not followed by \n must
|
|
* not be removed.
|
|
*/
|
|
struct ascii_to_bin_ret ret;
|
|
unsigned int indexx = 0;
|
|
unsigned int written = 0;
|
|
char* p_out = p_buf + 1;
|
|
ret.last_was_cr = 0;
|
|
if (prev_cr && (!in_len || p_out[0] != '\n'))
|
|
{
|
|
p_buf[0] = '\r';
|
|
ret.p_buf = p_buf;
|
|
written++;
|
|
}
|
|
else
|
|
{
|
|
ret.p_buf = p_out;
|
|
}
|
|
while (indexx < in_len)
|
|
{
|
|
char the_char = p_buf[indexx + 1];
|
|
if (the_char != '\r')
|
|
{
|
|
*p_out++ = the_char;
|
|
written++;
|
|
}
|
|
else if (indexx == in_len - 1)
|
|
{
|
|
ret.last_was_cr = 1;
|
|
}
|
|
else if (p_buf[indexx + 2] != '\n')
|
|
{
|
|
*p_out++ = the_char;
|
|
written++;
|
|
}
|
|
indexx++;
|
|
}
|
|
ret.stored = written;
|
|
return ret;
|
|
}
|
|
|
|
struct bin_to_ascii_ret
|
|
vsf_ascii_bin_to_ascii(const char* p_in,
|
|
char* p_out,
|
|
unsigned int in_len,
|
|
int prev_cr)
|
|
{
|
|
/* Task: translate all \n not preceeded by \r into \r\n.
|
|
* Note that \r\n stays as \r\n. We used to map it to \r\r\n like wu-ftpd
|
|
* but have switched to leaving it, like the more popular proftpd.
|
|
*/
|
|
struct bin_to_ascii_ret ret = { 0, 0 };
|
|
unsigned int indexx = 0;
|
|
unsigned int written = 0;
|
|
char last_char = 0;
|
|
if (prev_cr)
|
|
{
|
|
last_char = '\r';
|
|
ret.last_was_cr = 1;
|
|
}
|
|
while (indexx < in_len)
|
|
{
|
|
char the_char = p_in[indexx];
|
|
if (the_char == '\n' && last_char != '\r')
|
|
{
|
|
*p_out++ = '\r';
|
|
written++;
|
|
}
|
|
*p_out++ = the_char;
|
|
written++;
|
|
indexx++;
|
|
last_char = the_char;
|
|
if (the_char == '\r')
|
|
{
|
|
ret.last_was_cr = 1;
|
|
}
|
|
else
|
|
{
|
|
ret.last_was_cr = 0;
|
|
}
|
|
}
|
|
ret.stored = written;
|
|
return ret;
|
|
}
|
|
|