mirror of
https://github.com/curl/curl.git
synced 2026-08-26 19:23:32 +03:00
David McCreedy brought line end conversions when doing FTP ASCII
transfers. They are done on non-windows systems and translate CRLF to LF.
This commit is contained in:
parent
8ed6762363
commit
95152aec68
23 changed files with 380 additions and 214 deletions
113
lib/sendf.c
113
lib/sendf.c
|
|
@ -5,7 +5,7 @@
|
|||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
|
@ -139,6 +139,89 @@ void curl_slist_free_all(struct curl_slist *list)
|
|||
} while (next);
|
||||
}
|
||||
|
||||
#ifdef CURL_DO_LINEEND_CONV
|
||||
/*
|
||||
* convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
|
||||
* (\n), with special processing for CRLF sequences that are split between two
|
||||
* blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
|
||||
* size of the data is returned.
|
||||
*/
|
||||
static size_t convert_lineends(struct SessionHandle *data,
|
||||
char *startPtr, size_t size)
|
||||
{
|
||||
char *inPtr, *outPtr;
|
||||
|
||||
/* sanity check */
|
||||
if ((startPtr == NULL) || (size < 1)) {
|
||||
return(size);
|
||||
}
|
||||
|
||||
if (data->state.prev_block_had_trailing_cr == TRUE) {
|
||||
/* The previous block of incoming data
|
||||
had a trailing CR, which was turned into a LF. */
|
||||
if (*startPtr == '\n') {
|
||||
/* This block of incoming data starts with the
|
||||
previous block's LF so get rid of it */
|
||||
memcpy(startPtr, startPtr+1, size-1);
|
||||
size--;
|
||||
/* and it wasn't a bare CR but a CRLF conversion instead */
|
||||
data->state.crlf_conversions++;
|
||||
}
|
||||
data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
|
||||
}
|
||||
|
||||
/* find 1st CR, if any */
|
||||
inPtr = outPtr = memchr(startPtr, '\r', size);
|
||||
if (inPtr) {
|
||||
/* at least one CR, now look for CRLF */
|
||||
while (inPtr < (startPtr+size-1)) {
|
||||
/* note that it's size-1, so we'll never look past the last byte */
|
||||
if (memcmp(inPtr, "\r\n", 2) == 0) {
|
||||
/* CRLF found, bump past the CR and copy the NL */
|
||||
inPtr++;
|
||||
*outPtr = *inPtr;
|
||||
/* keep track of how many CRLFs we converted */
|
||||
data->state.crlf_conversions++;
|
||||
}
|
||||
else {
|
||||
if (*inPtr == '\r') {
|
||||
/* lone CR, move LF instead */
|
||||
*outPtr = '\n';
|
||||
}
|
||||
else {
|
||||
/* not a CRLF nor a CR, just copy whatever it is */
|
||||
*outPtr = *inPtr;
|
||||
}
|
||||
}
|
||||
outPtr++;
|
||||
inPtr++;
|
||||
} /* end of while loop */
|
||||
|
||||
if (inPtr < startPtr+size) {
|
||||
/* handle last byte */
|
||||
if (*inPtr == '\r') {
|
||||
/* deal with a CR at the end of the buffer */
|
||||
*outPtr = '\n'; /* copy a NL instead */
|
||||
/* note that a CRLF might be split across two blocks */
|
||||
data->state.prev_block_had_trailing_cr = TRUE;
|
||||
}
|
||||
else {
|
||||
/* copy last byte */
|
||||
*outPtr = *inPtr;
|
||||
}
|
||||
outPtr++;
|
||||
inPtr++;
|
||||
}
|
||||
if (outPtr < startPtr+size) {
|
||||
/* tidy up by null terminating the now shorter data */
|
||||
*outPtr = '\0';
|
||||
}
|
||||
return(outPtr - startPtr);
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
#endif /* CURL_DO_LINEEND_CONV */
|
||||
|
||||
/* Curl_infof() is for info message along the way */
|
||||
|
||||
void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
|
||||
|
|
@ -294,36 +377,36 @@ CURLcode Curl_client_write(struct SessionHandle *data,
|
|||
if(0 == len)
|
||||
len = strlen(ptr);
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(type & CLIENTWRITE_BODY) {
|
||||
if(data->ftp_in_ascii_mode) {
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* convert from the network encoding */
|
||||
size_t rc;
|
||||
rc = Curl_convert_from_network(data, ptr, len);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
if(rc != CURLE_OK) {
|
||||
return(rc);
|
||||
}
|
||||
if(rc != CURLE_OK)
|
||||
return rc;
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
#ifdef CURL_DO_LINEEND_CONV
|
||||
/* convert end-of-line markers */
|
||||
len = convert_lineends(data, ptr, len);
|
||||
#endif /* CURL_DO_LINEEND_CONV */
|
||||
}
|
||||
/* If the previous block of data ended with CR and this block of data is
|
||||
just a NL, then the length might be zero */
|
||||
if (len) {
|
||||
wrote = data->set.fwrite(ptr, 1, len, data->set.out);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
wrote = len;
|
||||
}
|
||||
|
||||
if(wrote != len) {
|
||||
failf (data, "Failed writing body");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(type & CLIENTWRITE_BODY) {
|
||||
wrote = data->set.fwrite(ptr, 1, len, data->set.out);
|
||||
if(wrote != len) {
|
||||
failf (data, "Failed writing body");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if((type & CLIENTWRITE_HEADER) &&
|
||||
(data->set.fwrite_header || data->set.writeheader) ) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue