session-initialize-bincimapd.cc (9276B)
1 /* -*- Mode: c++; -*- */ 2 /* -------------------------------------------------------------------- 3 * Filename: 4 * session-initialize-bincimap-up.cc 5 * 6 * Description: 7 * <---> 8 * 9 * Authors: 10 * Andreas Aardal Hanssen <andreas-binc curly bincimap spot org> 11 * 12 * Bugs: 13 * 14 * ChangeLog: 15 * 16 * -------------------------------------------------------------------- 17 * Copyright 2002-2005 Andreas Aardal Hanssen 18 * 19 * This program is free software; you can redistribute it and/or modify 20 * it under the terms of the GNU General Public License as published by 21 * the Free Software Foundation; either version 2 of the License, or 22 * (at your option) any later version. 23 * 24 * This program is distributed in the hope that it will be useful, 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * GNU General Public License for more details. 28 * 29 * You should have received a copy of the GNU General Public License 30 * along with this program; if not, write to the Free Software 31 * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 32 * -------------------------------------------------------------------- 33 */ 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> 36 #endif 37 38 #include <syslog.h> 39 40 #include "broker.h" 41 #include "maildir.h" 42 #include "depot.h" 43 #include "io-ssl.h" 44 #include "io.h" 45 #include "session.h" 46 #include "storage.h" 47 #include "tools.h" 48 #include "convert.h" 49 #include <string> 50 #include <map> 51 #include <signal.h> 52 53 using namespace ::std; 54 using namespace Binc; 55 56 extern char **environ; 57 58 namespace { 59 //------------------------------------------------------------------------ 60 void usage(char *name) 61 { 62 IO &logger = IOFactory::getInstance().get(2); 63 64 logger << "Please refer to the man pages for bincimap-up and bincimapd" 65 << endl; 66 logger << "for more information about how to invoke Binc IMAP." << endl; 67 logger.flushContent(); 68 } 69 } 70 71 //---------------------------------------------------------------------- 72 bool Session::initialize(int argc, char *argv[]) 73 { 74 IOFactory &iofactory = IOFactory::getInstance(); 75 iofactory.assign(1, new IO(stdout)); 76 iofactory.assign(2, new IO(stderr)); 77 78 IO &com = iofactory.get(1); 79 IO &logger = iofactory.get(2); 80 logger.disable(); 81 82 Session &session = Session::getInstance(); 83 84 session.importFromEnv(); 85 86 // Read command line arguments 87 if (!session.parseRequestLine(argc, argv)) 88 return false; 89 90 // Assign command line arguments to global config. 91 session.assignCommandLineArgs(); 92 93 // log settings 94 string ipenv = session.globalconfig["Log"]["ip environment variable"]; 95 // Initialize logger 96 string ip = getenv(ipenv.c_str()) ? getenv(ipenv.c_str()) : 97 getenv("TCPREMOTEIP") ? getenv("TCPREMOTEIP") : 98 getenv("REMOTEIP") ? getenv("REMOTEIP") : 99 getenv("SSLREMOTEIP") ? getenv("SSLREMOTEIP") : "?"; 100 session.setIP(ip); 101 102 if (session.globalconfig["Log"]["type"] == "multilog") { 103 logger.setLogPrefix(session.getUserID() + "@" + ip + ":"); 104 logger.enableLogPrefix(); 105 } else if (session.globalconfig["Log"]["type"] == "stderr" ) { 106 // stderr is the default 107 } else if (session.globalconfig["Log"]["type"] == "" 108 || session.globalconfig["Log"]["type"] == "syslog") { 109 const string f = session.globalconfig["Log"]["syslog facility"]; 110 const string fn = session.globalconfig["Log"]["syslog facility number"]; 111 112 int facility; 113 114 if (fn != "") facility = atoi(fn); 115 else { 116 if (f == "LOG_USER") facility = LOG_USER; 117 else if (f == "LOG_LOCAL0") facility = LOG_LOCAL0; 118 else if (f == "LOG_LOCAL1") facility = LOG_LOCAL1; 119 else if (f == "LOG_LOCAL2") facility = LOG_LOCAL2; 120 else if (f == "LOG_LOCAL3") facility = LOG_LOCAL3; 121 else if (f == "LOG_LOCAL4") facility = LOG_LOCAL4; 122 else if (f == "LOG_LOCAL5") facility = LOG_LOCAL5; 123 else if (f == "LOG_LOCAL6") facility = LOG_LOCAL6; 124 else if (f == "LOG_LOCAL7") facility = LOG_LOCAL7; 125 else facility = LOG_DAEMON; 126 } 127 128 session.globalconfig["Log"]["syslog facility number"] = toString(facility); 129 130 logger.setModeSyslog("bincimapd", facility); 131 } 132 133 logger.enable(); 134 135 // Now that we know the log type, we can flush. 136 logger.flushContent(); 137 logger.flushOnEndl(); 138 139 // Read command line arguments 140 if (!session.parseRequestLine(argc, argv)) { 141 logger << session.getLastError() << endl; 142 return false; 143 } 144 145 // Show help if asked for it 146 if (session.command.help) { 147 usage(argv[0]); 148 return false; 149 } 150 151 // Show help if asked for it 152 if (session.command.version) { 153 logger << "Binc IMAP v" << VERSION << endl; 154 return false; 155 } 156 157 char *logindetails = getenv("BINCIMAP_LOGIN"); 158 if (logindetails == 0) { 159 logger 160 << "BINCIMAP_LOGIN missing from environment (are you sure you invoked " 161 << argv[0] << " properly?)" << endl; 162 return false; 163 } 164 165 //----- 166 167 // try to read local settings. 168 Storage lconfig(".bincimap", Storage::ReadOnly); 169 string section, key, value; 170 while (lconfig.get(§ion, &key, &value)) 171 session.localconfig[section][key] = value; 172 173 string tmp; 174 if ((tmp = session.localconfig["Mailbox"]["depot"]) != "") 175 session.globalconfig["Mailbox"]["depot"] = tmp; 176 if ((tmp = session.localconfig["Mailbox"]["path"]) != "") 177 session.globalconfig["Mailbox"]["path"] = tmp; 178 if ((tmp = session.localconfig["Mailbox"]["type"]) != "") 179 session.globalconfig["Mailbox"]["type"] = tmp; 180 181 DepotFactory &depotfactory = DepotFactory::getInstance(); 182 depotfactory.assign(new IMAPdirDepot()); 183 depotfactory.assign(new MaildirPPDepot()); 184 185 string depottype = session.globalconfig["Mailbox"]["depot"]; 186 if (depottype == "") depottype = "Maildir++"; 187 188 if ((depot = depotfactory.get(depottype)) == 0) { 189 logger << "Found no Depot for \"" << depottype 190 << "\". Please check " 191 " your configurations file under the Mailbox section." 192 << endl; 193 logger.flushContent(); 194 return false; 195 } 196 197 depot->assign(new Maildir()); 198 depot->setDefaultType("Maildir"); 199 200 BrokerFactory &brokerfactory = BrokerFactory::getInstance(); 201 202 brokerfactory.assign("APPEND", new AppendOperator()); 203 brokerfactory.assign("CAPABILITY", new CapabilityOperator()); 204 brokerfactory.assign("CHECK", new CheckOperator()); 205 brokerfactory.assign("CLOSE", new CloseOperator()); 206 brokerfactory.assign("COPY", new CopyOperator()); 207 brokerfactory.assign("CREATE", new CreateOperator()); 208 brokerfactory.assign("DELETE", new DeleteOperator()); 209 brokerfactory.assign("EXAMINE", new ExamineOperator()); 210 brokerfactory.assign("EXPUNGE", new ExpungeOperator()); 211 brokerfactory.assign("FETCH", new FetchOperator()); 212 brokerfactory.assign("LIST", new ListOperator()); 213 brokerfactory.assign("LOGOUT", new LogoutOperator()); 214 brokerfactory.assign("LSUB", new LsubOperator()); 215 brokerfactory.assign("NOOP", new NoopPendingOperator()); 216 brokerfactory.assign("RENAME", new RenameOperator()); 217 brokerfactory.assign("SEARCH", new SearchOperator()); 218 brokerfactory.assign("SELECT", new SelectOperator()); 219 brokerfactory.assign("STATUS", new StatusOperator()); 220 brokerfactory.assign("STORE", new StoreOperator()); 221 brokerfactory.assign("SUBSCRIBE", new SubscribeOperator()); 222 brokerfactory.assign("UNSUBSCRIBE", new UnsubscribeOperator()); 223 224 string path = session.globalconfig["Mailbox"]["path"]; 225 if (session.args.getUnqualifiedArgs().size() > 0) 226 path = session.args.getUnqualifiedArgs()[0]; 227 if (path == "") path = "."; 228 else if (chdir(path.c_str()) != 0) { 229 mkdir(path.c_str(), 0777); 230 if (chdir(path.c_str()) != 0) { 231 logger << "when entering depot " + toImapString(path) + ": " 232 << strerror(errno) << endl; 233 return false; 234 } 235 } 236 237 if (depot->get("INBOX") == 0) { 238 if (session.globalconfig["Mailbox"]["auto create inbox"] == "yes") 239 if (!depot->createMailbox("INBOX")) { 240 logger << depot->getLastError() << endl; 241 return false; 242 } 243 } 244 245 // load subscription list 246 session.loadSubscribes(); 247 248 session.setState(Session::AUTHENTICATED); 249 250 // Read timeout settings from global config 251 idletimeout = atoi(session.globalconfig["Session"]["idle timeout"]); 252 if (idletimeout < 30 * 60) 253 idletimeout = 30 * 60; 254 255 transfertimeout = atoi(session.globalconfig["Session"]["transfer timeout"]); 256 257 // Set transfer timeout 258 com.setTransferTimeout(transfertimeout); 259 logger.setTransferTimeout(transfertimeout); 260 261 // Read transfer buffer size 262 int buffersize = atoi(session.globalconfig["Session"]["transfer buffer size"]); 263 com.setBufferSize(buffersize >= 0 ? buffersize : 0); 264 265 // umask settings 266 string umsk = session.globalconfig["Mailbox"]["umask"]; 267 if (umsk != "") { 268 unsigned int mode; 269 sscanf(session.globalconfig["Mailbox"]["umask"].c_str(), "%o", &mode); 270 umask((mode_t) mode); 271 } 272 273 const string details = logindetails; 274 string::size_type det = details.find('+'); 275 if (det == string::npos) { 276 logger << "invalid content of BINCIMAP_LOGIN - did you invoke " 277 << argv[0] << " correctly?" << endl; 278 return false; 279 } 280 281 const string tag = details.substr(det + 1); 282 const string command = details.substr(0, det); 283 com << tag << " OK " << command << " completed" << endl; 284 com.flushContent(); 285 286 return true; 287 }