summaryrefslogtreecommitdiffstats
path: root/libmail/mailtool.C
diff options
context:
space:
mode:
Diffstat (limited to 'libmail/mailtool.C')
-rw-r--r--libmail/mailtool.C1340
1 files changed, 1340 insertions, 0 deletions
diff --git a/libmail/mailtool.C b/libmail/mailtool.C
new file mode 100644
index 0000000..b060507
--- /dev/null
+++ b/libmail/mailtool.C
@@ -0,0 +1,1340 @@
+/*
+** Copyright 2002-2008, Double Precision Inc.
+**
+** See COPYING for distribution information.
+*/
+#include "libmail_config.h"
+#include "mail.H"
+#include "misc.H"
+#include "logininfo.H"
+#include "sync.H"
+#include "envelope.H"
+#include "structure.H"
+#include "maildir.H"
+#include "rfcaddr.H"
+#include "addmessage.H"
+#include "smtpinfo.H"
+#include "rfc822/rfc822.h"
+#include <cstring>
+
+#if HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include <sstream>
+#include <errno.h>
+
+using namespace std;
+
+static void error(string errmsg)
+{
+ cerr << "ERROR: " << errmsg << endl;
+ exit (1);
+}
+
+static void error(mail::ACCOUNT *p)
+{
+ error(p->errmsg);
+}
+
+extern "C" void rfc2045_error(const char *p)
+{
+ cerr << "ERROR: " << p << endl;
+ exit (0);
+}
+
+static void showenvelope(const mail::envelope &env, string pfix="")
+{
+ if (env.date > 0)
+ {
+ char buffer[200];
+
+ rfc822_mkdate_buf(env.date, buffer);
+ cout << pfix << " Date: " << buffer
+ << endl;
+ }
+
+ cout << pfix << " Subject: " << env.subject << endl;
+ cout << pfix << "In-ReplyTo: " << env.inreplyto
+ << endl;
+
+ vector<string>::const_iterator b=env.references.begin(),
+ e=env.references.end();
+
+ while (b != e)
+ {
+ cout << pfix << " Reference: <" << *b << ">" << endl;
+ b++;
+ }
+
+ cout << pfix << "Message-ID: " << env.messageid
+ << endl;
+ cout << pfix << mail::address::toString(" From: ",
+ env.from)
+ << endl;
+ cout << pfix << mail::address::toString(" Sender: ",
+ env.sender)
+ << endl;
+ cout << pfix << mail::address::toString(" Reply-To: ",
+ env.replyto)
+ << endl;
+ cout << pfix << mail::address::toString(" To: ",
+ env.to)
+ << endl;
+ cout << pfix << mail::address::toString(" Cc: ",
+ env.cc)
+ << endl;
+ cout << pfix << mail::address::toString(" Bcc: ",
+ env.bcc)
+ << endl;
+}
+
+static void showstructure(const mail::mimestruct &mps, string pfix="")
+{
+ cout << pfix << " Mime-ID: " << mps.mime_id << endl;
+ cout << pfix << " Content-Type: " << mps.type << "/"
+ << mps.subtype << endl;
+
+ mail::mimestruct::parameterList::const_iterator b, e;
+
+ b=mps.type_parameters.begin();
+ e=mps.type_parameters.end();
+
+ while (b != e)
+ {
+ cout << pfix << " "
+ << b->first << "=" << b->second << endl;
+ b++;
+ }
+
+ cout << pfix << " Content-Id: " << mps.content_id << endl;
+ cout << pfix << " Content-Description: " << mps.content_description
+ << endl;
+ cout << pfix << "Content-Transfer-Encoding: "
+ << mps.content_transfer_encoding << endl;
+ cout << pfix << " Size: " << mps.content_size
+ << endl;
+ cout << pfix << " Lines: " << mps.content_lines
+ << endl;
+ cout << pfix << " Content-MD5: " << mps.content_md5
+ << endl;
+ cout << pfix << " Content-Language: " << mps.content_language
+ << endl;
+ cout << pfix << " Content-Disposition: "
+ << mps.content_disposition << endl;
+
+ b=mps.content_disposition_parameters.begin();
+ e=mps.content_disposition_parameters.end();
+
+ while (b != e)
+ {
+ cout << pfix << " "
+ << b->first << "=" << b->second << endl;
+ b++;
+ }
+
+ if (mps.messagerfc822())
+ {
+ showenvelope(mps.getEnvelope(), pfix + " ");
+ }
+
+ size_t n=mps.getNumChildren();
+ size_t i;
+
+ for (i=0; i<n; i++)
+ {
+ cout << pfix
+ << "---------------------------------------------------"
+ << endl;
+ showstructure(*mps.getChild(i), pfix + " ");
+ }
+}
+
+static void showFolderList(mail::ACCOUNT *p,
+ mail::ACCOUNT::FolderList &list, int nestinglevel,
+ bool tree)
+{
+ vector<const mail::folder *> cpy;
+
+ cpy.insert(cpy.end(), list.begin(), list.end());
+
+ sort(cpy.begin(), cpy.end(), mail::folder::sort(false));
+
+ vector<const mail::folder *>::iterator
+ b=cpy.begin(), e=cpy.end();
+
+ bool extraSpace=false;
+
+ while (b != e)
+ {
+ const mail::folder *f= *b++;
+
+ if (extraSpace)
+ cout << endl;
+
+ extraSpace=false;
+
+ if (tree)
+ {
+ mail::ACCOUNT::FolderInfo info;
+
+ if (f->hasMessages())
+ p->readFolderInfo(f, info);
+
+ cout << setw(nestinglevel * 4 + 1) << " " << setw(0)
+ << f->getName();
+
+ if (info.unreadCount || info.messageCount)
+ {
+ cout << " (";
+ if (info.messageCount)
+ {
+ cout << info.messageCount << " messages";
+ if (info.unreadCount)
+ cout << ", ";
+ }
+
+ if (info.unreadCount)
+ cout << info.unreadCount << " unread";
+ cout << ")";
+ }
+
+ cout << endl;
+ }
+ else
+ {
+ cout << f->getPath() << endl;
+ }
+
+ if (f->hasSubFolders() || !f->hasMessages())
+ {
+ mail::ACCOUNT::FolderList subfolders;
+
+ if (p->getSubFolders(f, subfolders))
+ {
+ showFolderList(p, subfolders, nestinglevel+1,
+ tree);
+ extraSpace=tree;
+ }
+ else if (f->hasSubFolders())
+ {
+ error(p);
+ }
+ }
+ }
+}
+
+static void showEnvelope(mail::xenvelope &env)
+{
+ char date[100];
+
+ if (env.arrivalDate)
+ {
+ rfc822_mkdate_buf(env.arrivalDate, date);
+
+ cout << " Arrival-Date: " << date << endl;
+ }
+
+ cout << " Size: " << env.messageSize << endl;
+
+ if (env.date)
+ {
+ rfc822_mkdate_buf(env.date, date);
+
+ cout << " Date: " << date << endl;
+ }
+
+ cout << " Subject: " << env.subject << endl;
+ cout << " Message-Id: " << env.messageid << endl;
+ if (env.inreplyto.size() > 0)
+ cout << " In-Reply-To: " << env.inreplyto << endl;
+
+ vector<string>::const_iterator b=env.references.begin(),
+ e=env.references.end();
+
+ while (b != e)
+ {
+ cout << " Reference: <" << *b << ">" << endl;
+ b++;
+ }
+
+ if (env.from.size() > 0)
+ cout << mail::address::toString(" From: ", env.from)
+ << endl;
+
+ if (env.sender.size() > 0)
+ cout << mail::address::toString(" Sender: ", env.sender)
+ << endl;
+
+ if (env.replyto.size() > 0)
+ cout << mail::address::toString(" Reply-To: ",
+ env.replyto)<< endl;
+ if (env.to.size() > 0)
+ cout << mail::address::toString(" To: ", env.to)
+ << endl;
+
+ if (env.cc.size() > 0)
+ cout << mail::address::toString(" Cc: ",
+ env.cc) << endl;
+
+ if (env.bcc.size() > 0)
+ cout << mail::address::toString(" Bcc: ", env.bcc)
+ << endl;
+}
+
+static bool getIndex(mail::ACCOUNT *p, mail::folder *f)
+{
+ if (!p->openFolder(f, NULL))
+ return false;
+
+ size_t n=p->getFolderIndexSize();
+ size_t i;
+
+ vector<size_t> msgnums;
+
+ cout << "Total: " << n << " messages." << endl;
+
+#if 1
+ for (i=0; i<n; i++)
+ msgnums.push_back(i);
+
+ vector<mail::xenvelope> envelopes;
+
+ if (!p->getMessageEnvelope(msgnums, envelopes))
+ return false;
+
+ for (i=0; i<n; i++)
+ {
+ if (i > 0)
+ cout << endl;
+ cout << "Message " << (i+1) << ":" << endl;
+
+ showEnvelope(envelopes[i]);
+ }
+#endif
+
+#if 0
+ vector<mail::mimestruct> structures;
+
+ if (!p->getMessageStructure(msgnums, structures))
+ error(p);
+
+ vector<mail::mimestruct>::iterator b=structures.begin(),
+ e=structures.end();
+
+ i=0;
+ while (b != e)
+ {
+ cout << endl;
+ cout << "-------------------------------------------" << endl;
+ cout << " Message " << ++i << endl;
+ cout << "-------------------------------------------" << endl;
+ showstructure( *b++ );
+ }
+#endif
+ return true;
+
+}
+
+class DisplayHeader : public mail::ACCOUNT::Store {
+public:
+ DisplayHeader();
+ ~DisplayHeader();
+ void store(size_t, string);
+};
+
+DisplayHeader::DisplayHeader()
+{
+}
+
+DisplayHeader::~DisplayHeader()
+{
+}
+
+void DisplayHeader::store(size_t dummy, string txt)
+{
+ cout << txt;
+}
+
+static bool getHeaders(mail::ACCOUNT *p, mail::folder *f, size_t n)
+{
+ if (!p->openFolder(f, NULL))
+ return false;
+
+ vector<size_t> v;
+
+ v.push_back(n-1);
+
+ DisplayHeader display_header;
+
+ return (p->getMessageContent(v, false, mail::readHeadersFolded,
+ display_header));
+}
+
+static bool removeMessages(mail::ACCOUNT *p, mail::folder *f, const char *msgs)
+{
+ if (!p->openFolder(f, NULL))
+ return false;
+
+ vector<size_t> v;
+
+ while (*msgs)
+ {
+ if (!isdigit(*msgs))
+ {
+ msgs++;
+ continue;
+ }
+
+ size_t n=0;
+
+ while (*msgs && isdigit(*msgs))
+ n= n * 10 + (*msgs++ - '0');
+
+ if (n > 0)
+ {
+ cout << "Removing " << n << endl;
+ v.push_back(n-1);
+ }
+ }
+
+ cout << "Ready: ";
+
+ string reply;
+
+ if (getline(cin, reply).fail())
+ return true;
+
+ return (p->removeMessages(v));
+}
+
+static bool doFilterFolder(mail::ACCOUNT *p, mail::folder *f)
+{
+ if (!p->openFolder(f, NULL))
+ return false;
+
+ size_t n=p->getFolderIndexSize();
+
+ cout << "Total: " << n << " messages." << endl;
+
+ size_t i;
+
+ for (i=0; i<n; i++)
+ {
+ vector<size_t> msgnums;
+
+ msgnums.push_back(i);
+
+ vector<mail::xenvelope> envelopes;
+
+ if (!p->getMessageEnvelope(msgnums, envelopes))
+ return false;
+
+ cout << endl << "Message " << (i+1) << ":" << endl;
+ showEnvelope(envelopes[0]);
+
+ cout << "D)elete, S)kip, E)xit? (S) " << flush;
+
+ string reply;
+
+ if (getline(cin, reply).fail())
+ return true;
+
+ if (reply.size() == 0)
+ continue;
+
+ mail::messageInfo msgInfo=p->getFolderIndexInfo(n);
+
+ switch (reply[0]) {
+ case 'D':
+ case 'd':
+ msgInfo.deleted=true;
+
+ if (!p->saveFolderIndexInfo(n, msgInfo))
+ return false;
+ continue;
+ case 'E':
+ case 'e':
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+
+ p->updateFolderIndexInfo();
+
+ return true;
+}
+
+static bool doUploadMessage(mail::ACCOUNT *p, mail::folder *f)
+{
+ class uploadMessage : public mail::addMessagePull {
+ public:
+
+ string getMessageContents()
+ {
+ char buffer[BUFSIZ];
+
+ int n=read(0, buffer, sizeof(buffer));
+
+ if (n <= 0)
+ return "";
+
+ return (string(buffer, buffer+n));
+ }
+ };
+
+ uploadMessage upload;
+
+ return p->addMessage(f, upload);
+}
+
+class readStdin : public mail::addMessagePull {
+public:
+ readStdin();
+ ~readStdin();
+ string getMessageContents();
+};
+
+readStdin::readStdin()
+{
+}
+
+readStdin::~readStdin()
+{
+}
+
+string readStdin::getMessageContents()
+{
+ char buffer[BUFSIZ];
+
+ int n=cin.read(buffer, sizeof(buffer)).gcount();
+
+ if (n <= 0)
+ return "";
+
+ return string(buffer, buffer+n);
+}
+
+class copyProgressReporter : public mail::ACCOUNT::Progress {
+
+ string lastmsg;
+
+ static void fmtByte(ostringstream &o, size_t byteCount);
+
+ size_t lastCompletedShown;
+
+public:
+ size_t bytesCompleted, bytesEstimatedTotal,
+ messagesCompleted, messagesEstimatedTotal;
+
+ bool doReportProgress;
+ time_t timestamp;
+ bool final;
+
+ copyProgressReporter(mail::ACCOUNT *acct);
+ ~copyProgressReporter();
+
+ void operator()(size_t bytesCompleted,
+ size_t bytesEstimatedTotal,
+
+ size_t messagesCompleted,
+ size_t messagesEstimatedTotal);
+
+ void operator()();
+};
+
+copyProgressReporter::copyProgressReporter(mail::ACCOUNT *acct)
+ : Progress(acct), lastmsg(""),
+ lastCompletedShown(0),
+ bytesCompleted(0), bytesEstimatedTotal(0),
+ messagesCompleted(0), messagesEstimatedTotal(0),
+ doReportProgress(isatty(1) != 0), timestamp(time(NULL)),
+ final(false)
+{
+}
+
+copyProgressReporter::~copyProgressReporter()
+{
+}
+
+void copyProgressReporter::operator()(size_t bytesCompletedArg,
+ size_t bytesEstimatedTotalArg,
+
+ size_t messagesCompletedArg,
+ size_t messagesEstimatedTotalArg)
+{
+ bytesCompleted=bytesCompletedArg;
+ bytesEstimatedTotal=bytesEstimatedTotalArg;
+ messagesCompleted=messagesCompletedArg;
+ messagesEstimatedTotal=messagesEstimatedTotalArg;
+
+ if (!doReportProgress)
+ return;
+
+ time_t t=time(NULL);
+
+ if (t == timestamp)
+ return;
+
+ timestamp=t;
+
+ (*this)();
+}
+
+void copyProgressReporter::operator()()
+{
+ if (lastCompletedShown != messagesCompleted)
+ bytesCompleted=bytesEstimatedTotal=0;
+ // Background noise.
+
+ lastCompletedShown=messagesCompleted;
+
+ size_t i, n=lastmsg.size();
+
+ for (i=0; i<n; i++)
+ cout << '\b';
+ for (i=0; i<n; i++)
+ cout << ' ';
+ for (i=0; i<n; i++)
+ cout << '\b';
+
+ ostringstream o;
+
+ if (bytesCompleted)
+ {
+ fmtByte(o, bytesCompleted);
+
+ if (bytesCompleted < bytesEstimatedTotal)
+ {
+ o << " of ";
+ fmtByte(o, bytesEstimatedTotal);
+ }
+ }
+
+ if (final || messagesEstimatedTotal > 1)
+ {
+ if (bytesCompleted)
+ o << "; ";
+
+ o << messagesCompleted;
+ if (messagesCompleted < messagesEstimatedTotal)
+ o << " of " << messagesEstimatedTotal;
+ o << " msgs copied...";
+ }
+
+ lastmsg=o.str();
+ cout << lastmsg << flush;
+}
+
+void copyProgressReporter::fmtByte(ostringstream &o, size_t byteCount)
+{
+ if (byteCount < 1024)
+ {
+ o << byteCount;
+ return;
+ }
+
+ if (byteCount < 1024 * 1024)
+ {
+ o << (byteCount + 512) / 1024 << " Kb";
+ return;
+ }
+
+ o << byteCount / (1024 * 1024) << "."
+ << (byteCount % (1024 * 1024)) * 10 / (1024 * 1024) << " Mb";
+}
+
+static string docopyfolderordir(mail::ACCOUNT *fromAccount,
+ mail::ACCOUNT *toAccount,
+ mail::folder *fromfolder,
+ mail::folder *tofolder);
+
+static string docopyfolder(mail::ACCOUNT *fromAccount,
+ mail::ACCOUNT *toAccount,
+ mail::folder *fromfolder,
+ mail::folder *tofolder);
+
+
+static string docopy(mail::ACCOUNT *fromAccount,
+ mail::ACCOUNT *toAccount,
+ string fromFolderName,
+ string toFolderName,
+ bool recurse)
+{
+ string fromNameServer=fromFolderName, toNameServer=toFolderName;
+
+ mail::folder *fromfolder=
+ fromAccount->getFolderFromPath(fromNameServer);
+
+ if (!fromfolder)
+ return fromAccount->errmsg;
+
+ mail::folder *tofolder=
+ toAccount->getFolderFromPath(toNameServer);
+
+ if (!tofolder)
+ return toAccount->errmsg;
+
+ string errmsg=recurse ?
+ docopyfolderordir(fromAccount, toAccount,
+ fromfolder, tofolder)
+ : docopyfolder(fromAccount, toAccount,
+ fromfolder, tofolder);
+
+ delete fromfolder;
+ delete tofolder;
+ return errmsg;
+}
+
+static string docopyfolderordir(mail::ACCOUNT *fromAccount,
+ mail::ACCOUNT *toAccount,
+ mail::folder *fromfolder,
+ mail::folder *tofolder)
+{
+ if (fromfolder->hasSubFolders())
+ {
+ toAccount->createFolder(tofolder, true);
+ // Ignore error, subdirectory may already exist
+
+ mail::ACCOUNT::FolderList subfolders;
+
+ if (!fromAccount->getSubFolders(fromfolder, subfolders))
+ return fromfolder->getName() + ": " +
+ fromAccount->errmsg;
+
+ mail::ACCOUNT::FolderList::iterator b=subfolders.begin(),
+ e=subfolders.end();
+
+ while (b != e)
+ {
+ mail::folder *f= *b++;
+ string n=f->getName();
+
+ mail::folder *newFolder=
+ toAccount->createFolder(tofolder,
+ n,
+ !f->hasMessages());
+
+ if (!newFolder) // May already exist
+ {
+ mail::ACCOUNT::FolderList subfolders2;
+
+ if (!toAccount->getSubFolders(tofolder,
+ subfolders2))
+ return tofolder->getName() + ": "
+ + toAccount->errmsg;
+
+ mail::ACCOUNT::FolderList::iterator
+ sb=subfolders2.begin(),
+ se=subfolders2.end();
+
+ while (sb != se)
+ {
+ if ( (*sb)->getName() == n)
+ {
+ newFolder= (*sb)->clone();
+
+ if (!newFolder)
+ return strerror(errno);
+ break;
+ }
+ sb++;
+ }
+
+ if (!newFolder)
+ {
+ return tofolder->getName()
+ + ": cannot create "
+ + n;
+ }
+ }
+
+ string errmsg=docopyfolderordir(fromAccount,
+ toAccount,
+ f,
+ newFolder);
+
+ if (errmsg != "")
+ return errmsg;
+ delete newFolder;
+ }
+ if (!fromfolder->hasMessages())
+ return "";
+ }
+
+ return docopyfolder(fromAccount, toAccount, fromfolder, tofolder);
+}
+
+static string docopyfolder(mail::ACCOUNT *fromAccount,
+ mail::ACCOUNT *toAccount,
+ mail::folder *fromfolder,
+ mail::folder *tofolder)
+{
+ if (!fromAccount->openFolder(fromfolder, NULL))
+ return fromfolder->getName() + ": "
+ + fromAccount->errmsg;
+
+ toAccount->createFolder(tofolder, false); // May fail, ignore
+
+ {
+ mail::ACCOUNT::FolderInfo dummyInfo;
+
+ if (!toAccount->readFolderInfo(tofolder, dummyInfo))
+ return tofolder->getName() + ": " + toAccount->errmsg;
+ }
+
+ size_t n=fromAccount->getFolderIndexSize();
+
+ vector<size_t> copyvec;
+
+ copyvec.reserve(n);
+ size_t i;
+
+ for (i=0; i<n; i++)
+ copyvec.push_back(i);
+
+ {
+ copyProgressReporter progressReport(fromAccount);
+
+ cout << fromfolder->getName() << ": ";
+
+ if (!fromAccount->copyMessagesTo(copyvec, tofolder))
+ {
+ progressReport();
+ cout << endl;
+ return fromAccount->errmsg;
+ }
+ progressReport.bytesCompleted=0;
+ progressReport.bytesEstimatedTotal=0;
+ progressReport.messagesCompleted=n;
+ progressReport.messagesEstimatedTotal=n;
+ progressReport.final=true;
+ progressReport();
+ cout << endl;
+ }
+ return "";
+}
+
+static std::string pw_url;
+
+class pw_prompt : public mail::loginCallback {
+public:
+ pw_prompt();
+ ~pw_prompt();
+
+ void loginPrompt(callbackType cbType,
+ std::string prompt);
+};
+
+pw_prompt::pw_prompt()
+{
+}
+
+pw_prompt::~pw_prompt()
+{
+}
+
+
+void pw_prompt::loginPrompt(mail::loginCallback::callbackType theType,
+ std::string prompt)
+{
+#if HAVE_TERMIOS_H
+ struct termios ti;
+#endif
+
+ if (isatty(1))
+ {
+ if (pw_url.size() > 0)
+ cout << pw_url << "> ";
+
+ cout << prompt;
+
+#if HAVE_TERMIOS_H
+ if (theType == PASSWORD)
+ {
+ struct termios ti2;
+
+ if (tcgetattr(0, &ti))
+ {
+ perror("tcgetattr");
+ }
+
+ ti2=ti;
+
+ ti2.c_lflag &= ~ECHO;
+ tcsetattr(0, TCSAFLUSH, &ti2);
+ }
+#endif
+ }
+
+ char linebuf[80];
+
+ cin.getline(linebuf, sizeof(linebuf));
+
+#if HAVE_TERMIOS_H
+ if (isatty(1))
+ {
+ if (theType == PASSWORD)
+ {
+ cout << endl;
+ tcsetattr(0, TCSAFLUSH, &ti);
+ }
+ }
+#endif
+
+ char *p=strchr(linebuf, '\n');
+
+ if (p) *p=0;
+
+ callback(string(linebuf));
+}
+
+static void getExtraString(mail::account::openInfo &loginInfoArg)
+{
+ if (strncmp(loginInfoArg.url.c_str(), "nntp", 4) == 0)
+ {
+ const char *p=getenv("NEWSRC");
+
+ if (p && *p)
+ loginInfoArg.extraString=p;
+ else
+ loginInfoArg.extraString=
+ mail::homedir() + "/.newsrc";
+ return;
+ }
+
+ if (strncmp(loginInfoArg.url.c_str(), "pop3maildrop", 12) == 0)
+ {
+ cout << "maildrop (./Maildir): " << flush;
+
+ char linebuf[80];
+
+ cin.getline(linebuf, sizeof(linebuf));
+
+ char *p=strchr(linebuf, '\n');
+
+ if (p) *p=0;
+
+ if (linebuf[0] == 0)
+ strcpy(linebuf, "Maildir");
+
+ loginInfoArg.extraString=linebuf;
+ if (*loginInfoArg.extraString.c_str() != '/')
+ {
+ if (getcwd(linebuf, sizeof(linebuf)) == NULL)
+ {
+ perror("getcwd");
+ exit(1);
+ }
+
+ loginInfoArg.extraString= string(linebuf) + "/" +
+ loginInfoArg.extraString;
+ }
+ mail::maildir::maildirmake(loginInfoArg.extraString, false);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int argn=1;
+ const char *messagenum="0";
+
+ string path, newpath, name;
+ bool doCreate=false;
+ bool doCreateDir=false;
+ bool doDelete=false;
+ bool doDeleteDir=false;
+ bool doTree=false;
+ bool doList=false;
+ bool doIndex=false;
+ bool doHeaders=false;
+ bool doRemove=false;
+ bool doFilter=false;
+ bool doUpload=false;
+ bool doMail=false;
+ bool doRename=false;
+
+ bool doCopy=false;
+ bool doRecurse=false;
+ string copyto;
+ string tofolder;
+ string fromfolder;
+
+ mail::smtpInfo smtpInfo;
+
+ while (argn < argc)
+ {
+ if (strcmp(argv[argn], "-mailfrom") == 0 && argc - argn >= 2)
+ {
+ doMail=true;
+ smtpInfo.sender=argv[++argn];
+ ++argn;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-to") == 0 && argc - argn >= 2)
+ {
+ smtpInfo.recipients.push_back(argv[++argn]);
+ ++argn;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-opt") == 0 && argc - argn >= 3)
+ {
+ string opt=argv[++argn];
+ string val=argv[++argn];
+
+ smtpInfo.options.insert(make_pair(opt, val));
+ ++argn;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-create") == 0 && argc - argn >= 3)
+ {
+ path=argv[++argn];
+ name=argv[++argn];
+ ++argn;
+ doCreate=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-rename") == 0 && argc - argn >= 4)
+ {
+ path=argv[++argn];
+ newpath=argv[++argn];
+ name=argv[++argn];
+ ++argn;
+ doRename=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-createdir") == 0 && argc - argn >= 3)
+ {
+ path=argv[++argn];
+ name=argv[++argn];
+ ++argn;
+ doCreateDir=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-delete") == 0 && argc - argn >= 2)
+ {
+ path=argv[++argn];
+ ++argn;
+ doDelete=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-deletedir") == 0 && argc - argn >= 2)
+ {
+ path=argv[++argn];
+ ++argn;
+ doDeleteDir=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-tree") == 0)
+ {
+ doTree=true;
+ ++argn;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-list") == 0)
+ {
+ doList=true;
+ ++argn;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-index") == 0 && argc - argn >= 2)
+ {
+ path=argv[++argn];
+ ++argn;
+ doIndex=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-upload") == 0 && argc - argn >= 2)
+ {
+ path=argv[++argn];
+ ++argn;
+ doUpload=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-filter") == 0 && argc - argn >= 2)
+ {
+ path=argv[++argn];
+ ++argn;
+ doFilter=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-headers") == 0 && argc - argn >= 3)
+ {
+ path=argv[++argn];
+ messagenum=argv[++argn];
+ ++argn;
+ doHeaders=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-remove") == 0 && argc - argn >= 3)
+ {
+ path=argv[++argn];
+ messagenum=argv[++argn];
+ ++argn;
+ doRemove=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-copyto") == 0 && argc - argn >= 2)
+ {
+ copyto=argv[++argn];
+ ++argn;
+ doCopy=true;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-tofolder") == 0 && argc - argn >= 2)
+ {
+ tofolder=argv[++argn];
+ ++argn;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-fromfolder") == 0 && argc - argn >= 2)
+ {
+ fromfolder=argv[++argn];
+ ++argn;
+ continue;
+ }
+
+ if (strcmp(argv[argn], "-recurse") == 0)
+ {
+ doRecurse=true;
+ ++argn;
+ continue;
+ }
+ break;
+ }
+
+ if (argn >= argc)
+ exit (0);
+
+ string url=argv[argn];
+
+ mail::ACCOUNT *p=new mail::ACCOUNT();
+
+ if (!p)
+ {
+ cerr << strerror(errno) << endl;
+ exit (0);
+ }
+
+ mail::ACCOUNT::FolderList folderList;
+
+ pw_url=url;
+
+ {
+ pw_prompt getpassword;
+
+ mail::account::openInfo loginInfoArg;
+
+ loginInfoArg.url=url;
+
+ getExtraString(loginInfoArg);
+
+ loginInfoArg.loginCallbackObj= &getpassword;
+ if (!p->login(loginInfoArg) ||
+ !p->getTopLevelFolders(folderList))
+ {
+ error(p);
+ }
+ }
+
+ if (doCopy)
+ {
+ mail::ACCOUNT *toAccount=new mail::ACCOUNT();
+
+ if (!toAccount)
+ {
+ cerr << strerror(errno) << endl;
+ exit (0);
+ }
+
+ pw_url=copyto;
+
+ pw_prompt getpassword;
+
+ mail::account::openInfo loginInfo;
+
+ loginInfo.url=copyto;
+ loginInfo.loginCallbackObj= &getpassword;
+ getExtraString(loginInfo);
+
+ if (!toAccount->login(loginInfo))
+ {
+ error(toAccount);
+ }
+
+ string errmsg=docopy(p, toAccount, fromfolder, tofolder,
+ doRecurse);
+
+ if (errmsg.size() > 0)
+ error(errmsg);
+ toAccount->logout();
+ delete toAccount;
+ }
+ else if (doCreate || doCreateDir)
+ {
+ mail::folder *f=p->getFolderFromPath(path);
+
+ if (!f || !(f=p->createFolder(f, name, doCreateDir)))
+ {
+ error(p);
+ }
+ }
+ else if (doRename)
+ {
+ mail::folder *oldFolder=p->getFolderFromPath(path);
+
+ if (!oldFolder)
+ {
+ cerr << "ERROR: " << path << " - folder not found."
+ << endl;
+ exit(0);
+ }
+
+ mail::folder *newParent=NULL;
+
+ if (newpath.size() > 0)
+ {
+ newParent=p->getFolderFromPath(newpath);
+
+ if (!newParent)
+ {
+ cerr << "ERROR: " << newpath
+ << " - folder not found."
+ << endl;
+ exit(0);
+ }
+ }
+
+ if (!(oldFolder=p->renameFolder(oldFolder, newParent, name)))
+ error(p);
+ }
+ else if (doDelete || doDeleteDir)
+ {
+ mail::folder *f=p->getFolderFromPath(path);
+
+ if (!f || !p->deleteFolder(f, doDeleteDir))
+ {
+ error(p);
+ }
+ }
+ else if (doIndex)
+ {
+ mail::folder *f=p->getFolderFromPath(path);
+
+ if (!f || !getIndex(p, f))
+ error(p);
+
+#if 0
+ cout << "TOTAL # OF MESSAGES: " << p->getFolderIndexSize()
+ << endl;
+
+ string dummy;
+
+ getline(cin, dummy);
+
+ cout << "CHECK NEW MAIL: " << p->checkNewMail() << endl;
+
+ cout << "TOTAL # OF MESSAGES: " << p->getFolderIndexSize()
+ << endl;
+
+ if (!getIndex(p, f))
+ error(p);
+#endif
+ }
+ else if (doHeaders)
+ {
+ mail::folder *f=p->getFolderFromPath(path);
+
+ if (!f || !getHeaders(p, f, atoi(messagenum)))
+ error(p);
+ }
+ else if (doRemove)
+ {
+ mail::folder *f=p->getFolderFromPath(path);
+
+ if (!f || !removeMessages(p, f, messagenum))
+ error(p);
+ }
+ else if (doFilter)
+ {
+ mail::folder *f=p->getFolderFromPath(path);
+
+ if (!f || !doFilterFolder(p, f))
+ error(p);
+ }
+ else if (doUpload)
+ {
+ mail::folder *f=p->getFolderFromPath(path);
+
+ if (!f || !doUploadMessage(p, f))
+ error(p);
+ }
+ else if (doMail)
+ {
+ readStdin doReadStdin;
+
+ if (!p->send(smtpInfo, NULL, doReadStdin))
+ {
+ string errmsg=p->errmsg;
+ p->logout();
+ delete p;
+ error(errmsg);
+ }
+ }
+ else if (doTree || doList)
+ {
+ mail::ACCOUNT::FolderList::iterator b=folderList.begin(),
+ e=folderList.end();
+
+ while (b != e)
+ {
+ if ( (*b)->getPath().size() == 0)
+ break;
+
+ ++b;
+ }
+
+ if (b != e)
+ {
+ mail::ACCOUNT::FolderList subfolders;
+
+ if (!p->getSubFolders(*b, subfolders))
+ error(p);
+
+ showFolderList(p, subfolders, 0, doTree);
+ }
+ else
+ showFolderList(p, folderList, 0, doTree);
+ }
+
+ p->logout();
+
+ delete p;
+ exit(0);
+}