diff options
Diffstat (limited to 'src/session-initialize-bincimapd.cc')
-rw-r--r-- | src/session-initialize-bincimapd.cc | 213 |
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; +} |