]> code.citadel.org Git - citadel.git/blobdiff - libcitadel/lib/stringbuf.c
* add function to decode hex strings
[citadel.git] / libcitadel / lib / stringbuf.c
index 7db6017d600028d35fd366bb37272740f0bd2f31..c59361263d5b203c243389dea3266be4185ef6d2 100644 (file)
@@ -1414,7 +1414,7 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
                        *fd = -1;
                        return -1;
                }               
-               if (FD_ISSET(*fd, &rfds)) {
+               if (FD_ISSET(*fd, &rfds) != 0) {
                        rlen = read(*fd, 
                                    &buf->buf[buf->BufUsed], 
                                    buf->BufSize - buf->BufUsed - 1);
@@ -1524,12 +1524,15 @@ int StrBufReadBLOBBuffered(StrBuf *Buf,
                           int *fd, 
                           int append, 
                           long nBytes, 
+                          int check, 
                           const char **Error)
 {
+       int nSelects = 0;
+       int SelRes;
         fd_set wset;
         int fdflags;
        int len, rlen, slen;
-       int nRead;
+       int nRead = 0;
        char *ptr;
 
        if ((Buf == NULL) || (*fd == -1) || (IOBuf == NULL))
@@ -1569,24 +1572,43 @@ int StrBufReadBLOBBuffered(StrBuf *Buf,
 
        fdflags = fcntl(*fd, F_GETFL);
 
+       SelRes = 1;
        while (nRead < nBytes) {
-               if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
+               if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
                         FD_ZERO(&wset);
                         FD_SET(*fd, &wset);
-                        if (select(*fd + 1, NULL, &wset, NULL, NULL) == -1) {
-                               *Error = strerror(errno);
-                                return -1;
-                        }
-                }
-
-                if ((rlen = read(*fd, 
-                                ptr,
-                                nBytes - nRead)) == -1) {
-                       close(*fd);
-                       *fd = -1;
+                       SelRes = select(*fd + 1, NULL, &wset, NULL, NULL);
+               }
+               if (SelRes == -1) {
                        *Error = strerror(errno);
-                        return rlen;
-                }
+                       return -1;
+               }
+               else if (SelRes) {
+                       nSelects = 0;
+                       if ((rlen = read(*fd, 
+                                        ptr,
+                                        nBytes - nRead)) == -1) {
+                               close(*fd);
+                               *fd = -1;
+                               *Error = strerror(errno);
+                               return rlen;
+                       }
+               }
+               else {
+                       nSelects ++;
+                       if ((check == NNN_TERM) && 
+                           (nRead > 5) &&
+                           (strncmp(Buf->buf + Buf->BufUsed - 5, "\n000\n", 5) == 0)) 
+                       {
+                               StrBufPlain(IOBuf, HKEY("\n000\n"));
+                               StrBufCutRight(Buf, 5);
+                               return Buf->BufUsed;
+                       }
+                       if (nSelects > 10) {
+                               FlushStrBuf(Buf);
+                               return -1;
+                       }
+               }
                nRead += rlen;
                ptr += rlen;
                Buf->BufUsed += rlen;
@@ -1894,6 +1916,32 @@ int StrBufDecodeBase64(StrBuf *Buf)
        return siz;
 }
 
+/**
+ * \brief decode a buffer from base 64 encoding; destroys original
+ * \param Buf Buffor to transform
+ */
+int StrBufDecodeHex(StrBuf *Buf)
+{
+       unsigned int ch;
+       char *pch, *pche, *pchi;
+
+       if (Buf == NULL) return -1;
+
+       pch = pchi = Buf->buf;
+       pche = pch + Buf->BufUsed;
+
+       while (pchi < pche){
+               ch = decode_hex(pchi);
+               *pch = ch;
+               pch ++;
+               pchi += 2;
+       }
+
+       *pch = '\0';
+       Buf->BufUsed = pch - Buf->buf;
+       return Buf->BufUsed;
+}
+
 /**
  * \brief replace all chars >0x20 && < 0x7F with Mute
  * \param Mute char to put over invalid chars
@@ -2153,8 +2201,9 @@ inline static void DecodeSegment(StrBuf *Target,
        StrBuf StaticBuf;
        char charset[128];
        char encoding[16];
+#ifdef HAVE_ICONV
        iconv_t ic = (iconv_t)(-1);
-
+#endif
        /* Now we handle foreign character sets properly encoded
         * in RFC2047 format.
         */
@@ -2194,16 +2243,19 @@ inline static void DecodeSegment(StrBuf *Target,
        else {
                StrBufAppendBuf(ConvertBuf2, ConvertBuf, 0);
        }
-
+#ifdef HAVE_ICONV
        ctdl_iconv_open("UTF-8", charset, &ic);
        if (ic != (iconv_t)(-1) ) {             
+#endif
                StrBufConvert(ConvertBuf2, ConvertBuf, &ic);
                StrBufAppendBuf(Target, ConvertBuf2, 0);
+#ifdef HAVE_ICONV
                iconv_close(ic);
        }
        else {
                StrBufAppendBufPlain(Target, HKEY("(unreadable)"), 0);
        }
+#endif
 }
 /*
  * Handle subjects with RFC2047 encoding such as:
@@ -2213,7 +2265,9 @@ void StrBuf_RFC822_to_Utf8(StrBuf *Target, const StrBuf *DecodeMe, const StrBuf*
 {
        StrBuf *ConvertBuf, *ConvertBuf2;
        char *start, *end, *next, *nextend, *ptr = NULL;
+#ifdef HAVE_ICONV
        iconv_t ic = (iconv_t)(-1) ;
+#endif
        const char *eptr;
        int passes = 0;
        int i, len, delta;
@@ -2239,11 +2293,13 @@ void StrBuf_RFC822_to_Utf8(StrBuf *Target, const StrBuf *DecodeMe, const StrBuf*
            (strcasecmp(ChrPtr(DefaultCharset), "UTF-8")) && 
            (strcasecmp(ChrPtr(DefaultCharset), "us-ascii")) )
        {
+#ifdef HAVE_ICONV
                ctdl_iconv_open("UTF-8", ChrPtr(DefaultCharset), &ic);
                if (ic != (iconv_t)(-1) ) {
                        StrBufConvert((StrBuf*)DecodeMe, ConvertBuf, &ic);///TODO: don't void const?
                        iconv_close(ic);
                }
+#endif
        }
 
        /* pre evaluate the first pair */