]> code.citadel.org Git - citadel.git/blobdiff - libcitadel/lib/stringbuf.c
FileSendChunked(): replace sendfile by splice()
[citadel.git] / libcitadel / lib / stringbuf.c
index b5bcf22f7a24d11d4b452700e1f5bdb45bc7335f..79b5f5d2f3ab2116e0d2cd6604bf3db6e60a0f5e 100644 (file)
@@ -511,6 +511,7 @@ StrBuf* NewStrBufPlain(const char* ptr, int nChars)
 
        if (Siz == 0)
        {
+               free(NewBuf);
                return NULL;
        }
 
@@ -611,7 +612,7 @@ StrBuf* _NewConstStrBuf(const char* StringConstant, size_t SizeOfStrConstant)
  */
 int FlushStrBuf(StrBuf *buf)
 {
-       if (buf == NULL)
+       if ((buf == NULL) || (buf->buf == NULL))
                return -1;
        if (buf->ConstBuf)
                return -1;       
@@ -815,7 +816,8 @@ long StrBufPook(StrBuf *Buf, const char* ptr, long nThChar, long nChars, char Po
  */
 void StrBufAppendBuf(StrBuf *Buf, const StrBuf *AppendBuf, unsigned long Offset)
 {
-       if ((AppendBuf == NULL) || (Buf == NULL) || (AppendBuf->buf == NULL))
+       if ((AppendBuf == NULL) || (AppendBuf->buf == NULL) ||
+           (Buf == NULL) || (Buf->buf == NULL))
                return;
 
        if (Buf->BufSize - Offset < AppendBuf->BufUsed + Buf->BufUsed + 1)
@@ -1062,7 +1064,9 @@ void StrBufCutLeft(StrBuf *Buf, int nChars)
  */
 void StrBufCutRight(StrBuf *Buf, int nChars)
 {
-       if ((Buf == NULL) || (Buf->BufUsed == 0)) return;
+       if ((Buf == NULL) || (Buf->BufUsed == 0) || (Buf->buf == NULL))
+               return;
+
        if (nChars >= Buf->BufUsed) {
                FlushStrBuf(Buf);
                return;
@@ -1341,6 +1345,23 @@ int StrBufRemove_token(StrBuf *Source, int parmnum, char separator)
        return ReducedBy;
 }
 
+int StrBufExtract_tokenFromStr(StrBuf *dest, const char *Source, long SourceLen, int parmnum, char separator)
+{
+       const StrBuf Temp = {
+               (char*)Source,
+               SourceLen,
+               SourceLen,
+               1
+#ifdef SIZE_DEBUG
+               ,
+               0,
+               "",
+               ""
+#endif
+       };
+
+       return StrBufExtract_token(dest, &Temp, parmnum, separator);
+}
 
 /**
  * @ingroup StrBuf_Tokenizer
@@ -2500,14 +2521,14 @@ void StrBufEUid_unescapize(StrBuf *target, const StrBuf *source)
        int a, b, len;
        char hex[3];
 
-       if (target != NULL)
-               FlushStrBuf(target);
-
-       if (source == NULL ||target == NULL)
+       if ((source == NULL) || (target == NULL) || (target->buf == NULL))
        {
                return;
        }
 
+       if (target != NULL)
+               FlushStrBuf(target);
+
        len = source->BufUsed;
        for (a = 0; a < len; ++a) {
                if (target->BufUsed >= target->BufSize)
@@ -2544,7 +2565,7 @@ void StrBufEUid_escapize(StrBuf *target, const StrBuf *source)
        if (target != NULL)
                FlushStrBuf(target);
 
-       if (source == NULL ||target == NULL)
+       if ((source == NULL) || (target == NULL) || (target->buf == NULL))
        {
                return;
        }
@@ -2732,7 +2753,10 @@ int StrBufRFC2047encode(StrBuf **target, const StrBuf *source)
                        FlushStrBuf(*target);
                        StrBufAppendBuf(*target, source, 0);
                }
-               return (*target)->BufUsed;
+               if (*target != 0)
+                       return (*target)->BufUsed;
+               else
+                       return 0;
        }
        if (*target == NULL)
                *target = NewStrBufPlain(NULL, sizeof(headerStr) + source->BufUsed * 2);
@@ -3080,6 +3104,9 @@ void StrBufConvert(StrBuf *ConvertBuf, StrBuf *TmpBuf, void *pic)
        size_t obuflen;                 /**< Length of output buffer */
 
 
+       if ((ConvertBuf == NULL) || (TmpBuf == NULL))
+               return;
+
        /* since we're converting to utf-8, one glyph may take up to 6 bytes */
        if (ConvertBuf->BufUsed * 6 >= TmpBuf->BufSize)
                IncreaseBuf(TmpBuf, 0, ConvertBuf->BufUsed * 6);
@@ -3265,6 +3292,9 @@ void StrBuf_RFC822_2_Utf8(StrBuf *Target,
        int i;
        int illegal_non_rfc2047_encoding = 0;
 
+
+       if (DecodeMe == NULL)
+               return;
        /* Sometimes, badly formed messages contain strings which were simply
         *  written out directly in some foreign character set instead of
         *  using RFC2047 encoding.  This is illegal but we will attempt to
@@ -3751,6 +3781,10 @@ eReadState StrBufChunkSipLine(StrBuf *LineBuf, IOBuffer *FB)
        const char *aptr, *ptr, *eptr;
        char *optr, *xptr;
 
+       if ((FB == NULL) || (LineBuf == NULL) || (LineBuf->buf == NULL))
+               return eReadFail;
+       
+
        if ((FB->Buf == NULL) || (FB->ReadWritePointer == StrBufNOTNULL)) {
                FB->ReadWritePointer = StrBufNOTNULL;
                return eReadFail;
@@ -3838,6 +3872,8 @@ eReadState StrBufCheckBuffer(IOBuffer *FB)
 
 long IOBufferStrLength(IOBuffer *FB)
 {
+       if ((FB == NULL) || (FB->Buf == NULL))
+               return 0;
        if (FB->ReadWritePointer == NULL)
                return StrLength(FB->Buf);
        
@@ -3850,7 +3886,7 @@ void FDIOBufferInit(FDIOBuffer *FDB, IOBuffer *IO, int FD, long TotalSendSize)
        FDB->ChunkSize = 
                FDB->TotalSendSize = TotalSendSize;
        FDB->IOB = IO;
-#ifndef LINUX_SENDFILE
+#ifndef LINUX_SPLICE
        FDB->ChunkBuffer = NewStrBufPlain(NULL, TotalSendSize + 1);
 #else
        pipe(FDB->SplicePipe);
@@ -3860,7 +3896,7 @@ void FDIOBufferInit(FDIOBuffer *FDB, IOBuffer *IO, int FD, long TotalSendSize)
 
 void FDIOBufferDelete(FDIOBuffer *FDB)
 {
-#ifndef LINUX_SENDFILE
+#ifndef LINUX_SPLICE
        FreeStrBuf(&FDB->ChunkBuffer);
 #else
        close(FDB->SplicePipe[0]);
@@ -3873,18 +3909,38 @@ void FDIOBufferDelete(FDIOBuffer *FDB)
 
 int FileSendChunked(FDIOBuffer *FDB, const char **Err)
 {
-
-#ifdef LINUX_SENDFILE
-       ssize_t sent;
-       sent = sendfile(FDB->IOB->fd, FDB->OtherFD, &FDB->TotalSentAlready, FDB->ChunkSendRemain);
+       ssize_t sent, pipesize;
+#ifdef LINUX_SPLICE
+       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;
-       FDB->TotalSentAlready += sent;
-       return FDB->ChunkSendRemain;
+       return sent;
 #else
 
        char *pRead;
@@ -3920,26 +3976,37 @@ int FileRecvChunked(FDIOBuffer *FDB, const char **Err)
 {
        ssize_t sent, pipesize;
 
-#ifdef LINUX_SENDFILE
-
-       pipesize = splice(FDB->IOB->fd, NULL, 
-                         FDB->SplicePipe[1], NULL, 
-                         FDB->ChunkSendRemain, 
-                         SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK);
-       if (pipesize == -1)
+#ifdef LINUX_SPLICE
+       if (FDB->PipeSize == 0)
        {
-               *Err = strerror(errno);
-               return pipesize;
+               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);
+       sent = splice(FDB->SplicePipe[0],
+                     NULL, 
+                     FDB->OtherFD,
+                     &FDB->TotalSentAlready, 
+                     pipesize,
+                     SPLICE_F_MORE | SPLICE_F_MOVE);
+
        if (sent == -1)
        {
                *Err = strerror(errno);
                return sent;
        }
+       FDB->PipeSize -= sent;
        FDB->ChunkSendRemain -= sent;
        return sent;
 #else
@@ -4053,6 +4120,11 @@ int StrBufTCP_read_line(StrBuf *buf, int *fd, int append, const char **Error)
 {
        int len, rlen, slen;
 
+       if ((buf == NULL) || (buf->buf == NULL)) {
+               *Error = strerror(EINVAL);
+               return -1;
+       }
+
        if (!append)
                FlushStrBuf(buf);
 
@@ -4396,7 +4468,7 @@ int StrBufReadBLOB(StrBuf *Buf, int *fd, int append, long nBytes, const char **E
        struct timeval tv;
        fd_set rfds;
 
-       if ((Buf == NULL) || (*fd == -1))
+       if ((Buf == NULL) || (Buf->buf == NULL) || (*fd == -1))
        {
                *Error = ErrRBLF_BLOBPreConditionFailed;
                return -1;
@@ -4635,7 +4707,11 @@ int StrBufSipLine(StrBuf *LineBuf, const StrBuf *Buf, const char **Ptr)
        const char *aptr, *ptr, *eptr;
        char *optr, *xptr;
 
-       if ((Buf == NULL) || (*Ptr == StrBufNOTNULL)) {
+       if ((Buf == NULL) ||
+           (*Ptr == StrBufNOTNULL) ||
+           (LineBuf == NULL)||
+           (LineBuf->buf == NULL))
+       {
                *Ptr = StrBufNOTNULL;
                return 0;
        }