summaryrefslogtreecommitdiffstats
path: root/libmail/nntppost.C
diff options
context:
space:
mode:
Diffstat (limited to 'libmail/nntppost.C')
-rw-r--r--libmail/nntppost.C157
1 files changed, 157 insertions, 0 deletions
diff --git a/libmail/nntppost.C b/libmail/nntppost.C
new file mode 100644
index 0000000..88fbc10
--- /dev/null
+++ b/libmail/nntppost.C
@@ -0,0 +1,157 @@
+/*
+** Copyright 2003, Double Precision Inc.
+**
+** See COPYING for distribution information.
+*/
+#include "nntppost.H"
+#include <stdio.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <cstring>
+
+using namespace std;
+
+mail::nntp::PostTask::PostTask(callback *callbackArg, nntp &myserverArg,
+ FILE *msgArg)
+ : LoggedInTask(callbackArg, myserverArg), msg(msgArg),
+ myPumper(NULL)
+{
+}
+
+mail::nntp::PostTask::~PostTask()
+{
+ if (myPumper)
+ {
+ myPumper->writebuffer += "\r\n.\r\n";
+ myPumper->me=NULL;
+ }
+ if (msg)
+ fclose(msg);
+}
+
+void mail::nntp::PostTask::loggedIn()
+{
+ struct stat stat_buf;
+
+ if (fseek(msg, 0L, SEEK_SET) < 0 || fstat(fileno(msg), &stat_buf) < 0)
+ {
+ fail(strerror(errno));
+ return;
+ }
+
+ tot_count=stat_buf.st_size;
+ byte_count=0;
+ response_func= &mail::nntp::PostTask::doPostStatus;
+ myserver->socketWrite("POST\r\n");
+}
+
+void mail::nntp::PostTask::processLine(const char *message)
+{
+ (this->*response_func)(message);
+}
+
+mail::nntp::PostTask::pump::pump(PostTask *p) : newLine(true), me(p)
+{
+}
+
+mail::nntp::PostTask::pump::~pump()
+{
+ if (me)
+ me->myPumper=NULL;
+}
+
+bool mail::nntp::PostTask::pump::fillWriteBuffer()
+{
+ if (!me)
+ return false;
+
+ char buffer[BUFSIZ];
+
+ int n=fread(buffer, 1, sizeof(buffer), me->msg);
+
+ if (n <= 0)
+ {
+ if (!newLine)
+ writebuffer += "\r\n";
+ writebuffer += ".\r\n";
+ me->myPumper=NULL;
+ me=NULL;
+ return true;
+ }
+
+ // Copy the read chunk into the writebuffer, convert NLs to CRNLs,
+ // and dot-stuffing.
+
+ char *b=buffer, *e=b + n, *c=b;
+
+ while (b != e)
+ {
+ if (newLine && *b == '.') // Leading dot, double it.
+ {
+ writebuffer.insert(writebuffer.end(), c, b+1);
+ c=b; // Net effect is the dot doubled.
+ }
+
+ if ((newLine= *b == '\n') != 0)
+ {
+ if (c != b)
+ writebuffer.insert(writebuffer.end(), c, b);
+ writebuffer += "\r";
+ c=b;
+ }
+ b++;
+ }
+
+ if (c != b)
+ writebuffer.insert(writebuffer.end(), c, b);
+
+ me->byte_count += n;
+
+ if (me->tot_count < me->byte_count)
+ me->tot_count=me->byte_count;
+
+ me->callbackPtr->reportProgress(me->byte_count, me->tot_count, 0, 1);
+ return true;
+}
+
+void mail::nntp::PostTask::doPostStatus(const char *resp)
+{
+ if (resp[0] != '3')
+ {
+ fail(resp);
+ return;
+ }
+
+ response_func= &mail::nntp::PostTask::doPost;
+ pump *p=new pump(this);
+
+ if (p)
+ try {
+ myserver->socketWrite(p);
+ myPumper=p;
+ return;
+ } catch (...) {
+ delete p;
+ }
+
+ myserver->socketWrite(".\r\n");
+}
+
+void mail::nntp::PostTask::doPost(const char *msg)
+{
+ if (myPumper)
+ {
+ myPumper->writebuffer += "\r\n.\r\n";
+ myPumper->me=NULL;
+ }
+ myPumper=NULL;
+
+ switch (msg[0]) {
+ case '2':
+ case '1':
+ success(msg);
+ break;
+ default:
+ fail(msg);
+ }
+}