summaryrefslogtreecommitdiffstats
path: root/libmail/file.C
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /libmail/file.C
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'libmail/file.C')
-rw-r--r--libmail/file.C191
1 files changed, 191 insertions, 0 deletions
diff --git a/libmail/file.C b/libmail/file.C
new file mode 100644
index 0000000..2820a72
--- /dev/null
+++ b/libmail/file.C
@@ -0,0 +1,191 @@
+/*
+** Copyright 2002, Double Precision Inc.
+**
+** See COPYING for distribution information.
+*/
+#include "libmail_config.h"
+#include "file.H"
+#include "unicode/unicode.h"
+#include <ctype.h>
+
+using namespace std;
+
+/////////////////////////////////////////////////////////////////////////////
+
+mail::file::file(int fdArg, const char *mode)
+ : fd(dup(fdArg)), fp(NULL), pos(-1)
+{
+ if (fd >= 0)
+ fp=fdopen(fd, mode);
+
+ if (fp && fseek(fp, 0L, SEEK_SET) < 0)
+ {
+ fclose(fp);
+ fp=NULL;
+ }
+}
+
+mail::file::~file()
+{
+ if (fp != NULL)
+ fclose(fp);
+
+ if (fd >= 0)
+ close(fd);
+}
+
+void mail::file::seeked()
+{
+ if (fp)
+ pos=ftell(fp);
+}
+
+string mail::file::getline()
+{
+ // First time through, allocate a 1000 bye buffer.
+
+ if (buffer.size() != 1000)
+ {
+ buffer.clear();
+ buffer.insert(buffer.end(), 1000, 0);
+ }
+
+ string l;
+
+ for (;;)
+ {
+ vector<char>::iterator b=buffer.begin(), e=buffer.end();
+
+ while (b != e)
+ {
+ int ch=getc(fp);
+
+ if (ch == EOF)
+ break;
+ if (pos != -1)
+ pos++;
+
+ *b++ = ch;
+ if (ch == '\n')
+ break;
+ }
+
+ if (b == buffer.begin())
+ break; // EOF
+
+ if (b[-1] != '\n')
+ {
+ l.insert(l.end(), buffer.begin(), b);
+ continue;
+ }
+
+
+ --b;
+ l.insert(l.end(), buffer.begin(), b);
+ break;
+ }
+
+ size_t n=l.size();
+
+ if (n > 0 && l[n-1] == '\r')
+ l=l.substr(0, n-1);
+ return l;
+}
+
+
+void mail::file::genericMessageRead(mail::account *account,
+ size_t messageNumber,
+ mail::readMode readType,
+ mail::callback::message &callback)
+{
+ ptr<mail::account> ptrAccount(account);
+
+ if (readType == mail::readHeadersFolded
+ || readType == mail::readHeaders)
+ {
+ string hdr="";
+
+ string l;
+
+ while (!ptrAccount.isDestroyed() && !feof(fp) && !ferror(fp))
+ {
+ l=getline();
+
+ if (l.size() == 0)
+ break;
+
+ if (unicode_isspace((unsigned char)l[0]))
+ {
+ const char *p=l.c_str();
+
+ if (readType == mail::readHeaders)
+ hdr += "\n";
+ else // Fold headers
+ {
+ hdr += " ";
+
+ while (*p &&
+ unicode_isspace((unsigned char)
+ *p))
+ p++;
+ }
+ hdr += p;
+ continue;
+ }
+
+ if (hdr.size() > 0) // Prev header.
+ {
+ hdr += "\n";
+ callback.messageTextCallback(messageNumber,
+ hdr);
+ }
+ hdr=l;
+ }
+
+ if (hdr.size() > 0 && !ptrAccount.isDestroyed())
+ {
+ hdr += "\n";
+ callback.messageTextCallback(messageNumber, hdr);
+ }
+ return;
+ }
+
+ if (readType == mail::readContents)
+ // Skip over the header portion.
+ {
+ while (!feof(fp) && !ferror(fp))
+ {
+ if (getline().size() == 0)
+ break;
+ }
+ }
+
+ vector<char> buffer;
+
+ buffer.insert(buffer.end(), BUFSIZ, 0);
+
+ size_t i=0;
+
+ int ch;
+
+ while (!ptrAccount.isDestroyed() && (ch=getc(fp)) != EOF)
+ {
+ if (ch == '\r')
+ continue;
+
+ if (i >= buffer.size())
+ {
+ callback.messageTextCallback(messageNumber,
+ string(buffer.begin(),
+ buffer.end()));
+ i=0;
+ }
+
+ buffer[i++]=ch;
+ }
+
+ if (i > 0 && !ptrAccount.isDestroyed())
+ callback.messageTextCallback(messageNumber,
+ string(buffer.begin(),
+ buffer.begin()+i));
+}