diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /libmail/mailtool.C | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-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/mailtool.C')
| -rw-r--r-- | libmail/mailtool.C | 1340 | 
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); +} | 
