summaryrefslogtreecommitdiff
path: root/src/session-initialize-bincimapd.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/session-initialize-bincimapd.cc')
-rw-r--r--src/session-initialize-bincimapd.cc213
1 files changed, 213 insertions, 0 deletions
diff --git a/src/session-initialize-bincimapd.cc b/src/session-initialize-bincimapd.cc
new file mode 100644
index 0000000..18d43b1
--- /dev/null
+++ b/src/session-initialize-bincimapd.cc
@@ -0,0 +1,213 @@
+/** --------------------------------------------------------------------
+ * @file session-initialize-bincimapd.cc
+ * @brief <--->
+ * @author Andreas Aardal Hanssen, Erwin Hoffmann
+ * @date 2002-2005, 2023
+ * --------------------------------------------------------------------
+ */
+#include <unistd.h>
+#include <syslog.h>
+#include <errno.h>
+
+#include "broker.h"
+#include "maildir.h"
+#include "depot.h"
+#include "globals.h"
+#include "iodevice.h"
+#include "iofactory.h"
+#include "multilogdevice.h"
+#include "session.h"
+#include "stdiodevice.h"
+#include "syslogdevice.h"
+#include "tools.h"
+#include "convert.h"
+#include "imapserver.h"
+
+#include <string>
+#include <map>
+#include <signal.h>
+
+using namespace ::std;
+using namespace Binc;
+
+extern char **environ;
+
+//----------------------------------------------------------------------
+bool Session::initialize(int argc, char *argv[])
+{
+ IOFactory &ioFactory = IOFactory::getInstance();
+
+ IODevice *stdioDevice = new StdIODevice(IODevice::IsEnabled
+ | IODevice::HasInputLimit
+ | IODevice::HasTimeout);
+ stdioDevice->setFlags(IODevice::HasOutputLimit);
+ stdioDevice->setMaxOutputBufferSize(TRANSFER_BUFFER_SIZE);
+ ioFactory.addDevice(stdioDevice);
+
+ Session &session = Session::getInstance();
+
+ // Read command line arguments
+ if (!session.parseCommandLine(argc, argv))
+ return false;
+
+ // Show help if asked for it
+ if (session.command.help) {
+ printf("%s\n", session.args.usageString().c_str());
+ return false;
+ }
+
+ // Show version if asked for it
+ if (session.command.version) {
+ printf("Binc IMAP v" BINC_VERSION"\n");
+ return false;
+ }
+
+ // Assign command line arguments to global config.
+ session.assignCommandLineArgs();
+
+ // log settings
+ string ip = getenv("TCP6REMOTEIP") ? getenv("TCP6REMOTEIP") :
+ getenv("TCPREMOTEIP") ? getenv("TCPREMOTEIP") : "?";
+ session.setIP(ip);
+
+ string logtype = session.getEnv("LOG_TYPE");
+ lowercase(logtype);
+ trim(logtype);
+ if (logtype == "" || logtype == "multilog" ) {
+ ioFactory.addDevice(new MultilogDevice(IODevice::IsEnabled));
+ } else if (logtype == "syslog") {
+ const string f = session.getEnv("SYSLOG_FACILITY");
+
+ int facility;
+
+ if (isdigit(f[0])) facility = atoi(f);
+ else {
+ if (f == "LOG_USER") facility = LOG_USER;
+ else if (f == "LOG_LOCAL0") facility = LOG_LOCAL0;
+ else if (f == "LOG_LOCAL1") facility = LOG_LOCAL1;
+ else if (f == "LOG_LOCAL2") facility = LOG_LOCAL2;
+ else if (f == "LOG_LOCAL3") facility = LOG_LOCAL3;
+ else if (f == "LOG_LOCAL4") facility = LOG_LOCAL4;
+ else if (f == "LOG_LOCAL5") facility = LOG_LOCAL5;
+ else if (f == "LOG_LOCAL6") facility = LOG_LOCAL6;
+ else if (f == "LOG_LOCAL7") facility = LOG_LOCAL7;
+ else facility = LOG_DAEMON;
+ }
+
+ session.setEnv("SYSLOG_FACILITY", toString(facility));
+
+ ioFactory.addDevice(new SyslogDevice(IODevice::IsEnabled,
+ "bincimapd",
+ LOG_NDELAY | LOG_PID,
+ facility));
+ }
+
+ // Now that we know the log type, we can flush.
+ IOFactory::getLogger().flush();
+ IOFactory::getLogger().setFlags(IODevice::FlushesOnEndl);
+ IOFactory::getLogger().setOutputLevelLimit(IODevice::InfoLevel);
+
+ string pid = to_string(session.getPid());
+
+ char *logindetails = getenv("BINCIMAP_LOGIN");
+ if (logindetails == 0) {
+ bincLog
+ << "bincimapd: pid " << pid
+ << " BINCIMAP_LOGIN missing from environment (are you sure you invoked "
+ << argv[0] << " properly?)\n";
+ return false;
+ }
+
+ DepotFactory &depotfactory = DepotFactory::getInstance();
+ depotfactory.assign(new IMAPdirDepot());
+ depotfactory.assign(new MaildirPPDepot());
+
+ string depottype = session.getEnv("DEPOT");
+ if (depottype == "") depottype = "Maildir++";
+
+ if ((depot = depotfactory.get(depottype)) == 0) {
+ bincLog << "bincimapd: pid " << pid
+ << " Found no Depot for: " << depottype
+ << ". Please check your configurations file under the Mailbox section\n";
+ bincLog.flush();
+ return false;
+ }
+
+ depot->assign(new Maildir());
+ depot->setDefaultType("Maildir");
+
+ // Configurable delimiter to ease crossover from other IMAPservers
+ string delimiter = session.getEnv("DELIMITER");
+ if (delimiter != "") depot->setDelimiter(delimiter[0]);
+
+ BrokerFactory &brokerfactory = BrokerFactory::getInstance();
+
+ brokerfactory.assign("APPEND", new AppendOperator());
+ brokerfactory.assign("CAPABILITY", new CapabilityOperator());
+ brokerfactory.assign("CHECK", new CheckOperator());
+ brokerfactory.assign("CLOSE", new CloseOperator());
+ brokerfactory.assign("COPY", new CopyOperator());
+ brokerfactory.assign("CREATE", new CreateOperator());
+ brokerfactory.assign("DELETE", new DeleteOperator());
+ brokerfactory.assign("EXAMINE", new ExamineOperator());
+ brokerfactory.assign("EXPUNGE", new ExpungeOperator());
+ brokerfactory.assign("FETCH", new FetchOperator());
+ brokerfactory.assign("IDLE", new IdleOperator());
+ brokerfactory.assign("ID", new IdOperator());
+ brokerfactory.assign("LIST", new ListOperator());
+ brokerfactory.assign("LOGOUT", new LogoutOperator());
+ brokerfactory.assign("LSUB", new LsubOperator());
+ brokerfactory.assign("NAMESPACE", new NamespaceOperator());
+ brokerfactory.assign("NOOP", new NoopPendingOperator());
+ brokerfactory.assign("RENAME", new RenameOperator());
+ brokerfactory.assign("SEARCH", new SearchOperator());
+ brokerfactory.assign("SELECT", new SelectOperator());
+ brokerfactory.assign("STATUS", new StatusOperator());
+ brokerfactory.assign("STORE", new StoreOperator());
+ brokerfactory.assign("SUBSCRIBE", new SubscribeOperator());
+ brokerfactory.assign("UNSUBSCRIBE", new UnsubscribeOperator());
+
+ // automatically create depot directory if it's not there already
+ string path;
+ if (session.args.getUnqualifiedArgs().size() > 0)
+ path = session.args.getUnqualifiedArgs()[0];
+ if (path == "") path = ".";
+ else if (chdir(path.c_str()) != 0) {
+ mkdir(path.c_str(), 0777);
+ if (chdir(path.c_str()) != 0) {
+ bincLog << "bincimapd: pid" << pid
+ << " Error entering depot " + toImapString(path) + ": "
+ << strerror(errno) << endl;
+ return false;
+ }
+ }
+
+ // automatically create INBOX if it's not there already
+ if (depot->get("INBOX") == 0 && !depot->createMailbox("INBOX")) {
+ bincLog << "bincimapd: pid " << pid
+ << " " << depot->getLastError() << endl;
+ return false;
+ }
+
+ // load subscription list
+ depot->loadSubscribes();
+
+ session.setState(Session::AUTHENTICATED);
+
+ const string details = logindetails;
+ string::size_type det = details.find('+');
+ if (det == string::npos) {
+ bincLog << "bincimapd: pid " << pid
+ << " Invalid content of BINCIMAP_LOGIN - did you invoke "
+ << argv[0] << " correctly?" << endl;
+ return false;
+ }
+
+ const string tag = details.substr(det + 1);
+ const string command = details.substr(0, det);
+ bincClient << tag << " OK " << command << " completed" << endl;
+ bincClient.flush();
+ bincClient.setTimeout(IDLE_TIMEOUT);
+
+ return true;
+}