X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=libcitadel%2Flib%2Fstringbuf.c;h=9bc1c8eb04aa9015ab7f5d62abdd50fe5b2d0175;hb=3c0b1d8686c302e511389e2afbbbf436af2c56e9;hp=359538d9611584c957bd032062ff9840be85607e;hpb=31c5406616d5990e183627edbb7e6c324da0bf03;p=citadel.git diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c index 359538d96..9bc1c8eb0 100644 --- a/libcitadel/lib/stringbuf.c +++ b/libcitadel/lib/stringbuf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2013 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,8 +40,8 @@ #include #endif -#ifdef LINUX_SENDFILE -#include +#ifdef UNDEF_MEMCPY +#undef memcpy #endif #ifdef HAVE_ZLIB @@ -50,6 +50,7 @@ int ZEXPORT compress_gzip(Bytef * dest, size_t * destLen, const Bytef * source, uLong sourceLen, int level); #endif int BaseStrBufSize = 64; +int EnableSplice = 0; const char *StrBufNOTNULL = ((char*) NULL) - 1; @@ -361,7 +362,12 @@ long StrBufShrinkToFit(StrBuf *Buf, int Force) if (Force || (Buf->BufUsed + (Buf->BufUsed / 3) > Buf->BufSize)) { - char *TmpBuf = (char*) malloc(Buf->BufUsed + 1); + char *TmpBuf; + + TmpBuf = (char*) malloc(Buf->BufUsed + 1); + if (TmpBuf == NULL) + return -1; + memcpy (TmpBuf, Buf->buf, Buf->BufUsed + 1); Buf->BufSize = Buf->BufUsed + 1; free(Buf->buf); @@ -380,7 +386,15 @@ StrBuf* NewStrBuf(void) StrBuf *NewBuf; NewBuf = (StrBuf*) malloc(sizeof(StrBuf)); + if (NewBuf == NULL) + return NULL; + NewBuf->buf = (char*) malloc(BaseStrBufSize); + if (NewBuf->buf == NULL) + { + free(NewBuf); + return NULL; + } NewBuf->buf[0] = '\0'; NewBuf->BufSize = BaseStrBufSize; NewBuf->BufUsed = 0; @@ -405,7 +419,16 @@ StrBuf* NewStrBufDup(const StrBuf *CopyMe) return NewStrBuf(); NewBuf = (StrBuf*) malloc(sizeof(StrBuf)); + if (NewBuf == NULL) + return NULL; + NewBuf->buf = (char*) malloc(CopyMe->BufSize); + if (NewBuf->buf == NULL) + { + free(NewBuf); + return NULL; + } + memcpy(NewBuf->buf, CopyMe->buf, CopyMe->BufUsed + 1); NewBuf->BufUsed = CopyMe->BufUsed; NewBuf->BufSize = CopyMe->BufSize; @@ -501,6 +524,9 @@ StrBuf* NewStrBufPlain(const char* ptr, int nChars) size_t CopySize; NewBuf = (StrBuf*) malloc(sizeof(StrBuf)); + if (NewBuf == NULL) + return NULL; + if (nChars < 0) CopySize = strlen((ptr != NULL)?ptr:""); else @@ -594,6 +620,8 @@ StrBuf* _NewConstStrBuf(const char* StringConstant, size_t SizeOfStrConstant) StrBuf *NewBuf; NewBuf = (StrBuf*) malloc(sizeof(StrBuf)); + if (NewBuf == NULL) + return NULL; NewBuf->buf = (char*) StringConstant; NewBuf->BufSize = SizeOfStrConstant; NewBuf->BufUsed = SizeOfStrConstant; @@ -1022,16 +1050,18 @@ int StrBufSub(StrBuf *dest, const StrBuf *Source, unsigned long Offset, size_t n } if (Offset + nChars < Source->BufUsed) { - if (nChars >= dest->BufSize) - IncreaseBuf(dest, 0, nChars + 1); + if ((nChars >= dest->BufSize) && + (IncreaseBuf(dest, 0, nChars + 1) == -1)) + return 0; memcpy(dest->buf, Source->buf + Offset, nChars); dest->BufUsed = nChars; dest->buf[dest->BufUsed] = '\0'; return nChars; } NCharsRemain = Source->BufUsed - Offset; - if (NCharsRemain >= dest->BufSize) - IncreaseBuf(dest, 0, NCharsRemain + 1); + if ((NCharsRemain >= dest->BufSize) && + (IncreaseBuf(dest, 0, NCharsRemain + 1) == -1)) + return 0; memcpy(dest->buf, Source->buf + Offset, NCharsRemain); dest->BufUsed = NCharsRemain; dest->buf[dest->BufUsed] = '\0'; @@ -1143,29 +1173,31 @@ void StrBufSpaceToBlank(StrBuf *Buf) void StrBufStripAllBut(StrBuf *Buf, char leftboundary, char rightboundary) { - const char *pBuff; const char *pLeft; const char *pRight; - if ((Buf == NULL) || (Buf->buf == NULL)) + if ((Buf == NULL) || (Buf->buf == NULL)) { + StrBufCutAt(Buf, 0, Buf->buf); return; - pLeft = pBuff = Buf->buf; - while (pBuff != NULL) { - pLeft = pBuff; - pBuff = strchr(pBuff, leftboundary); - if (pBuff != NULL) - pBuff++; } - - if (pLeft != NULL) - pBuff = pLeft; - else - pBuff = Buf->buf; - pRight = strchr(pBuff, rightboundary); - if (pRight != NULL) + + pRight = strchr(Buf->buf, rightboundary); + if (pRight != NULL) { StrBufCutAt(Buf, 0, pRight); - if (pLeft != NULL) - StrBufCutLeft(Buf, pLeft - Buf->buf); + } + else { + StrBufCutAt(Buf, 0, Buf->buf); + return; + } + + pLeft = strrchr(ChrPtr(Buf), leftboundary); + if (pLeft != NULL) { + StrBufCutLeft(Buf, pLeft - Buf->buf + 1); + } + else { + StrBufCutAt(Buf, 0, Buf->buf); + return; + } } @@ -2510,6 +2542,23 @@ long StrHtmlEcmaEscAppend(StrBuf *Target, const StrBuf *Source, const char *Plai return Target->BufUsed; } + +/** + * @ingroup StrBuf_DeEnCoder + * @brief replace all non-Ascii characters by another + * @param Buf buffer to inspect + * @param repl charater to stamp over non ascii chars + */ +void StrBufAsciify(StrBuf *Buf, const char repl) +{ + long offset; + + for (offset = 0; offset < Buf->BufUsed; offset ++) + if (!isascii(Buf->buf[offset])) + Buf->buf[offset] = repl; + +} + /** * @ingroup StrBuf_DeEnCoder * @brief unhide special chars hidden to the HTML escaper @@ -2603,9 +2652,14 @@ int StrBufDecodeBase64(StrBuf *Buf) { char *xferbuf; size_t siz; - if (Buf == NULL) return -1; + + if (Buf == NULL) + return -1; xferbuf = (char*) malloc(Buf->BufSize); + if (xferbuf == NULL) + return -1; + *xferbuf = '\0'; siz = CtdlDecodeBase64(xferbuf, Buf->buf, @@ -3886,69 +3940,102 @@ void FDIOBufferInit(FDIOBuffer *FDB, IOBuffer *IO, int FD, long TotalSendSize) FDB->ChunkSize = FDB->TotalSendSize = TotalSendSize; FDB->IOB = IO; -#ifndef LINUX_SPLICE - FDB->ChunkBuffer = NewStrBufPlain(NULL, TotalSendSize + 1); -#else - pipe(FDB->SplicePipe); +#ifdef LINUX_SPLICE + if (EnableSplice) + pipe(FDB->SplicePipe); + else #endif + FDB->ChunkBuffer = NewStrBufPlain(NULL, TotalSendSize + 1); + FDB->OtherFD = FD; } void FDIOBufferDelete(FDIOBuffer *FDB) { -#ifndef LINUX_SPLICE - FreeStrBuf(&FDB->ChunkBuffer); -#else - close(FDB->SplicePipe[0]); - close(FDB->SplicePipe[1]); - +#ifdef LINUX_SPLICE + if (EnableSplice) + { + if (FDB->SplicePipe[0] > 0) + close(FDB->SplicePipe[0]); + if (FDB->SplicePipe[1] > 0) + close(FDB->SplicePipe[1]); + } + else #endif - close(FDB->OtherFD); + FreeStrBuf(&FDB->ChunkBuffer); + + if (FDB->OtherFD > 0) + close(FDB->OtherFD); memset(FDB, 0, sizeof(FDIOBuffer)); } int FileSendChunked(FDIOBuffer *FDB, const char **Err) { + ssize_t sent, pipesize; #ifdef LINUX_SPLICE - ssize_t sent; - sent = sendfile(FDB->IOB->fd, FDB->OtherFD, &FDB->TotalSentAlready, FDB->ChunkSendRemain); - if (sent == -1) + if (EnableSplice) { - *Err = strerror(errno); + if (FDB->PipeSize == 0) + { + pipesize = splice(FDB->OtherFD, + &FDB->TotalSentAlready, + FDB->SplicePipe[1], + NULL, + FDB->ChunkSendRemain, + SPLICE_F_MOVE); + + if (pipesize == -1) + { + *Err = strerror(errno); + return pipesize; + } + FDB->PipeSize = pipesize; + } + sent = splice(FDB->SplicePipe[0], + NULL, + FDB->IOB->fd, + NULL, + FDB->PipeSize, + SPLICE_F_MORE | SPLICE_F_MOVE | SPLICE_F_NONBLOCK); + if (sent == -1) + { + *Err = strerror(errno); + return sent; + } + FDB->PipeSize -= sent; + FDB->ChunkSendRemain -= sent; return sent; } - FDB->ChunkSendRemain -= sent; - FDB->TotalSentAlready += sent; - return FDB->ChunkSendRemain; -#else - - char *pRead; - long nRead = 0; - - pRead = FDB->ChunkBuffer->buf; - while ((FDB->ChunkBuffer->BufUsed < FDB->TotalSendSize) && (nRead >= 0)) + else +#endif { - nRead = read(FDB->OtherFD, pRead, FDB->TotalSendSize - FDB->ChunkBuffer->BufUsed); - if (nRead > 0) { - FDB->ChunkBuffer->BufUsed += nRead; - FDB->ChunkBuffer->buf[FDB->ChunkBuffer->BufUsed] = '\0'; - } - else if (nRead == 0) {} - else return nRead; + char *pRead; + long nRead = 0; + + pRead = FDB->ChunkBuffer->buf; + while ((FDB->ChunkBuffer->BufUsed < FDB->TotalSendSize) && (nRead >= 0)) + { + nRead = read(FDB->OtherFD, pRead, FDB->TotalSendSize - FDB->ChunkBuffer->BufUsed); + if (nRead > 0) { + FDB->ChunkBuffer->BufUsed += nRead; + FDB->ChunkBuffer->buf[FDB->ChunkBuffer->BufUsed] = '\0'; + } + else if (nRead == 0) {} + else return nRead; - } + } - nRead = write(FDB->IOB->fd, FDB->ChunkBuffer->buf + FDB->TotalSentAlready, FDB->ChunkSendRemain); + nRead = write(FDB->IOB->fd, FDB->ChunkBuffer->buf + FDB->TotalSentAlready, FDB->ChunkSendRemain); - if (nRead >= 0) { - FDB->TotalSentAlready += nRead; - FDB->ChunkSendRemain -= nRead; - return FDB->ChunkSendRemain; - } - else { - return nRead; + if (nRead >= 0) { + FDB->TotalSentAlready += nRead; + FDB->ChunkSendRemain -= nRead; + return FDB->ChunkSendRemain; + } + else { + return nRead; + } } -#endif } int FileRecvChunked(FDIOBuffer *FDB, const char **Err) @@ -3956,64 +4043,143 @@ int FileRecvChunked(FDIOBuffer *FDB, const char **Err) ssize_t sent, pipesize; #ifdef LINUX_SPLICE - - pipesize = splice(FDB->IOB->fd, - NULL, - FDB->SplicePipe[1], - NULL, - FDB->ChunkSendRemain, - SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK); - - if (pipesize == -1) + if (EnableSplice) { - *Err = strerror(errno); - return pipesize; - } + if (FDB->PipeSize == 0) + { + pipesize = splice(FDB->IOB->fd, + NULL, + FDB->SplicePipe[1], + NULL, + FDB->ChunkSendRemain, + SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK); + + if (pipesize == -1) + { + *Err = strerror(errno); + return pipesize; + } + FDB->PipeSize = pipesize; + } - sent = splice(FDB->SplicePipe[0], - NULL, - FDB->OtherFD, - &FDB->TotalSentAlready, - pipesize, - SPLICE_F_MORE | SPLICE_F_MOVE); - - if (sent == -1) - { - *Err = strerror(errno); + sent = splice(FDB->SplicePipe[0], + NULL, + FDB->OtherFD, + &FDB->TotalSentAlready, + FDB->PipeSize, + SPLICE_F_MORE | SPLICE_F_MOVE); + + if (sent == -1) + { + *Err = strerror(errno); + return sent; + } + FDB->PipeSize -= sent; + FDB->ChunkSendRemain -= sent; return sent; } - FDB->ChunkSendRemain -= sent; - return sent; -#else - - sent = read(FDB->IOB->fd, FDB->ChunkBuffer->buf, FDB->ChunkSendRemain); - if (sent > 0) { - int nWritten = 0; - int rc; + else +#endif + { + sent = read(FDB->IOB->fd, FDB->ChunkBuffer->buf, FDB->ChunkSendRemain); + if (sent > 0) { + int nWritten = 0; + int rc; - FDB->ChunkBuffer->BufUsed = sent; + FDB->ChunkBuffer->BufUsed = sent; + + while (nWritten < FDB->ChunkBuffer->BufUsed) { + rc = write(FDB->OtherFD, FDB->ChunkBuffer->buf + nWritten, FDB->ChunkBuffer->BufUsed - nWritten); + if (rc < 0) { + *Err = strerror(errno); + return rc; + } + nWritten += rc; - while (nWritten < FDB->ChunkBuffer->BufUsed) { - rc = write(FDB->OtherFD, FDB->ChunkBuffer->buf + nWritten, FDB->ChunkBuffer->BufUsed - nWritten); - if (rc < 0) { - *Err = strerror(errno); - return rc; } - nWritten += rc; + FDB->ChunkBuffer->BufUsed = 0; + FDB->TotalSentAlready += sent; + FDB->ChunkSendRemain -= sent; + return FDB->ChunkSendRemain; + } + else if (sent < 0) { + *Err = strerror(errno); + return sent; + } + return 0; + } +} + +int FileMoveChunked(FDIOBuffer *FDB, const char **Err) +{ + ssize_t sent, pipesize; +#ifdef LINUX_SPLICE + if (EnableSplice) + { + if (FDB->PipeSize == 0) + { + pipesize = splice(FDB->IOB->fd, + &FDB->TotalReadAlready, + FDB->SplicePipe[1], + NULL, + FDB->ChunkSendRemain, + SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK); + + if (pipesize == -1) + { + *Err = strerror(errno); + return pipesize; + } + FDB->PipeSize = pipesize; } - FDB->ChunkBuffer->BufUsed = 0; - FDB->TotalSentAlready += sent; + + sent = splice(FDB->SplicePipe[0], + NULL, + FDB->OtherFD, + &FDB->TotalSentAlready, + FDB->PipeSize, + SPLICE_F_MORE | SPLICE_F_MOVE); + + if (sent == -1) + { + *Err = strerror(errno); + return sent; + } + FDB->PipeSize -= sent; FDB->ChunkSendRemain -= sent; - return FDB->ChunkSendRemain; - } - else if (sent < 0) { - *Err = strerror(errno); return sent; } + else +#endif + { + sent = read(FDB->IOB->fd, FDB->ChunkBuffer->buf, FDB->ChunkSendRemain); + if (sent > 0) { + int nWritten = 0; + int rc; + + FDB->ChunkBuffer->BufUsed = sent; -#endif - return 0; + while (nWritten < FDB->ChunkBuffer->BufUsed) { + rc = write(FDB->OtherFD, FDB->ChunkBuffer->buf + nWritten, FDB->ChunkBuffer->BufUsed - nWritten); + if (rc < 0) { + *Err = strerror(errno); + return rc; + } + nWritten += rc; + + } + FDB->ChunkBuffer->BufUsed = 0; + FDB->TotalSentAlready += sent; + FDB->ChunkSendRemain -= sent; + return FDB->ChunkSendRemain; + } + else if (sent < 0) { + *Err = strerror(errno); + return sent; + } + return 0; + } } eReadState WriteIOBAlreadyRead(FDIOBuffer *FDB, const char **Error) @@ -4206,10 +4372,11 @@ int StrBufTCP_read_buffered_line(StrBuf *Line, nSuccessLess = 0; buf->BufUsed += rlen; buf->buf[buf->BufUsed] = '\0'; - if (buf->BufUsed + 10 > buf->BufSize) { - IncreaseBuf(buf, 1, -1); - } pch = strchr(buf->buf, '\n'); + if ((pch == NULL) && + (buf->BufUsed + 10 > buf->BufSize) && + (IncreaseBuf(buf, 1, -1) == -1)) + return -1; continue; } @@ -4399,6 +4566,10 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line, continue; } + else + { + nSuccessLess++; + } } *Pos = NULL; if (pLF != NULL) { @@ -4535,9 +4706,12 @@ int StrBufReadBLOBBuffered(StrBuf *Blob, int nSuccessLess = 0; int MaxTries; - if ((Blob == NULL) || (*fd == -1) || (IOBuf == NULL) || (Pos == NULL)) + if ((Blob == NULL) || + (*fd == -1) || + (IOBuf == NULL) || + (Pos == NULL)) { - if (*Pos != NULL) + if (Pos != NULL) *Pos = NULL; *Error = ErrRBB_BLOBFPreConditionFailed; return -1;