bincimap-up.cc (5637B)
1 /* -*- Mode: c++; -*- */ 2 /* -------------------------------------------------------------------- 3 * Filename: 4 * bincimap-up.cc 5 * 6 * Description: 7 * Implementation of the preauthenticated bincimap stub 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 <string> 39 40 #include "broker.h" 41 #include "recursivedescent.h" 42 #include "io.h" 43 #ifdef WITH_SSL 44 #include "io-ssl.h" 45 #endif 46 #include "operators.h" 47 #include "session.h" 48 49 using namespace ::std; 50 using namespace Binc; 51 52 namespace Binc { 53 bool showGreeting(void); 54 } 55 56 //------------------------------------------------------------------------ 57 int main(int argc, char *argv[]) 58 { 59 Session &session = Session::getInstance(); 60 if (!session.initialize(argc, argv)) { 61 if (session.getLastError() != "") { 62 IO &logger = IOFactory::getInstance().get(2); 63 logger << "error initializing Binc IMAP: " << session.getLastError() 64 << endl; 65 logger.flushContent(); 66 } 67 return 111; 68 } 69 70 IO &com = IOFactory::getInstance().get(1); 71 IO &logger = IOFactory::getInstance().get(2); 72 73 logger << "connection from " << session.getIP() << endl; 74 75 // Show standard greeting 76 showGreeting(); 77 bool recovery = false; 78 bool timedout = false; 79 bool disconnect = false; 80 bool abrt = false; 81 82 // Read commands and run functions 83 do { 84 com.enableInputLimit(); 85 86 // recover from syntax error. There will be trash in the input 87 // buffer. We need to flush everything until we see an LF. 88 if (recovery) { 89 for (;;) { 90 int c = com.readChar(session.timeout()); 91 if (c == '\n') break; 92 if (c == -1) { 93 disconnect = true; 94 abrt = true; 95 break; 96 } else if (c == -2) { 97 com << "* BYE Timeout after " << session.timeout() 98 << " seconds of inactivity." << endl; 99 timedout = true; 100 abrt = true; 101 break; 102 } 103 } 104 105 if (abrt) 106 break; 107 } 108 109 Request request; 110 recovery = false; 111 112 BrokerFactory &brokerFactory = BrokerFactory::getInstance(); 113 Broker *broker = brokerFactory.getBroker(session.getState()); 114 if (!broker) { 115 // will never happen 116 } 117 118 com.flushContent(); 119 com.noFlushOnEndl(); 120 121 switch (broker->parseStub(request)) { 122 case Operator::TIMEOUT: 123 com << "* BYE Timeout after " << session.timeout() 124 << " seconds of inactivity." << endl; 125 timedout = true; 126 abrt = true; 127 break; 128 case Operator::REJECT: 129 com << "* NO " << session.getLastError() << endl; 130 recovery = true; 131 continue; 132 case Operator::ERROR: 133 com << "* BAD " << session.getLastError() << endl; 134 recovery = true; 135 continue; 136 default: 137 break; 138 } 139 140 if (abrt) 141 break; 142 143 Operator *o = broker->get(request.getName()); 144 if (!o) { 145 com << request.getTag() << " NO The command \"" 146 << (request.getUidMode() ? "UID " : "") 147 << request.getName() 148 << "\" is unsupported in this state. " 149 << "Please authenticate." << endl; 150 recovery = true; 151 continue; 152 } 153 154 switch (o->parse(request)) { 155 case Operator::TIMEOUT: 156 com << "* BYE Timeout after " << session.timeout() 157 << " seconds of inactivity." << endl; 158 timedout = true; 159 abrt = true; 160 break; 161 case Operator::REJECT: 162 com << "* NO " << session.getLastError() << endl; 163 recovery = true; 164 continue; 165 case Operator::ERROR: 166 com << "* BAD " << session.getLastError() << endl; 167 recovery = true; 168 continue; 169 default: 170 break; 171 } 172 173 switch (o->process(*session.getDepot(), request)) { 174 case Operator::OK: 175 com << request.getTag() << " OK " << request.getName() 176 << " completed" << endl; 177 break; 178 case Operator::NO: 179 com << request.getTag() << " NO " << session.getResponseCode() 180 << request.getName() << " failed: " << session.getLastError() << endl; 181 session.clearResponseCode(); 182 break; 183 case Operator::BAD: 184 com << request.getTag() << " BAD " << request.getName() 185 << " failed: " << session.getLastError() << endl; 186 recovery = true; 187 break; 188 case Operator::NOTHING: 189 break; 190 case Operator::ABORT: 191 session.setState(Session::LOGOUT); 192 abrt = true; 193 break; 194 } 195 196 if (abrt) 197 break; 198 } while (session.getState() != Session::LOGOUT); 199 200 logger << "shutting down "; 201 if (timedout) 202 logger << "(timeout " + toString(session.timeout()) + "s) "; 203 else if (disconnect) 204 logger << "(" << com.getLastError() << ") "; 205 206 logger << "- read:" 207 << session.getReadBytes() 208 << " bytes, wrote:" << session.getWriteBytes() 209 << " bytes." << endl; 210 211 com.flushContent(); 212 }