00001
00002
00003
00004
00005
00006
00007 #include "Core.h"
00008 #include "TcpConnection.h"
00009 #include "Registry.h"
00010
00011 #include "FSh.h"
00012
00013
00014
00015 FSh::FSh(const ValueList ¶ms) : Service<FSh>(params),
00016 _connection(NULL),
00017 _getLine(NULL),
00018 _telnet(NULL),
00019 _logErrors(false),
00020 _logErrorsRe("", RE_Options().set_caseless(true)),
00021 _logWarnings(false),
00022 _logWarningsRe("", RE_Options().set_caseless(true)),
00023 _logDebug(false),
00024 _logDebugRe("", RE_Options().set_caseless(true))
00025 {
00026 BIND(colors__on);
00027
00028 BIND(log__errors__on);
00029 BIND(log__errors__regexp);
00030 BIND(log__warnings__on);
00031 BIND(log__warnings__regexp);
00032 BIND(log__debug__on);
00033 BIND(log__debug__regexp);
00034
00035 int res;
00036
00037 if (params.size() < 1) {
00038 failure(ERROR(SERVICE_MSG_INVALID_PARAMS, CSTRING(NAME())));
00039 return;
00040 }
00041
00042 ValueObject *obj = queryInterface<ValueObject>(params[0]);
00043 if (!obj || !(_connection = queryInterface<TcpConnection>(obj->get()))) {
00044 failure(ERROR(SERVICE_MSG_INVALID_PARAM_TYPE, CSTRING(NAME())));
00045 return;
00046 }
00047
00048 if (FAILED(res = start())) {
00049 failure(ERROR_BACKTRACE(res));
00050 return;
00051 }
00052 }
00053
00054 FSh::~FSh()
00055 {
00056 if (_telnet)
00057 delete _telnet;
00058 if (_getLine)
00059 delete _getLine;
00060 if (_connection)
00061 delete _connection;
00062 }
00063
00064
00065
00066 int FSh::start()
00067 {
00068 String re;
00069 bool yes;
00070 int res;
00071
00072 if (FAILED(res = REGISTRY_GET(FSh, log__errors__on, yes, this)))
00073 return ERROR_BACKTRACE(res);
00074 if (FAILED(res = setLogErrorsEnabled(yes)))
00075 return ERROR_BACKTRACE(res);
00076
00077 if (FAILED(res = REGISTRY_GET(FSh, log__errors__regexp, re, this)))
00078 return ERROR_BACKTRACE(res);
00079 if (FAILED(res = setLogErrorsRegexp(re)))
00080 return ERROR_BACKTRACE(res);
00081
00082 if (FAILED(res = REGISTRY_GET(FSh, log__warnings__on, yes, this)))
00083 return ERROR_BACKTRACE(res);
00084 if (FAILED(res = setLogWarningsEnabled(yes)))
00085 return ERROR_BACKTRACE(res);
00086
00087 if (FAILED(res = REGISTRY_GET(FSh, log__warnings__regexp, re, this)))
00088 return ERROR_BACKTRACE(res);
00089 if (FAILED(res = setLogWarningsRegexp(re)))
00090 return ERROR_BACKTRACE(res);
00091
00092 if (FAILED(res = REGISTRY_GET(FSh, log__debug__on, yes, this)))
00093 return ERROR_BACKTRACE(res);
00094 if (FAILED(res = setLogDebugEnabled(yes)))
00095 return ERROR_BACKTRACE(res);
00096
00097 if (FAILED(res = REGISTRY_GET(FSh, log__debug__regexp, re, this)))
00098 return ERROR_BACKTRACE(res);
00099 if (FAILED(res = setLogDebugRegexp(re)))
00100 return ERROR_BACKTRACE(res);
00101
00102 if (FAILED(res = _connection->setNonBlock()))
00103 return ERROR_BACKTRACE(res);
00104
00105 if (!(_getLine = new FShGetLine(this)))
00106 return ERROR(MSG_OBJECT_CANNOT_CREATE, "FShGetLine");
00107 if (FAILED(res = _getLine->failureCode()))
00108 return ERROR_BACKTRACE(res);
00109
00110 if (!(_telnet = new Telnet(_connection, _getLine)))
00111 return ERROR(MSG_OBJECT_CANNOT_CREATE, "Telnet");
00112 if (FAILED(res = _telnet->failureCode()))
00113 return ERROR_BACKTRACE(res);
00114
00115 if (FAILED(res = _telnet->iac(DO, TELOPT_NAWS, 0, 0, 0, 0)))
00116 return ERROR_BACKTRACE(res);
00117 if (FAILED(res = _telnet->iac(DO, TELOPT_TTYPE, 0, 0, 0, 0)))
00118 return ERROR_BACKTRACE(res);
00119 if (FAILED(res = _telnet->iac(WILL, TELOPT_ECHO, 0, 0, 0, 0)))
00120 return ERROR_BACKTRACE(res);
00121 if (FAILED(res = _telnet->iac(WILL, TELOPT_SGA, 0, 0, 0, 0)))
00122 return ERROR_BACKTRACE(res);
00123
00124 if (FAILED(res = CONNECT(_connection, dataReady, this, FSh, dataReady)))
00125 return ERROR_BACKTRACE(res);
00126
00127 if (FAILED(res = CONNECT(_connection, dead, this, FSh, die)))
00128 return ERROR_BACKTRACE(res);
00129
00130 if (FAILED(res = CONNECT(colors__on(), set, this, FSh, setColorEnabled)))
00131 return ERROR_BACKTRACE(res);
00132
00133 if (FAILED(res = CONNECT(log__errors__on(), set, this, FSh, setLogErrorsEnabled)))
00134 return ERROR_BACKTRACE(res);
00135 if (FAILED(res = CONNECT(log__errors__regexp(), set, this, FSh, setLogErrorsRegexp)))
00136 return ERROR_BACKTRACE(res);
00137
00138 if (FAILED(res = CONNECT(log__warnings__on(), set, this, FSh, setLogWarningsEnabled)))
00139 return ERROR_BACKTRACE(res);
00140 if (FAILED(res = CONNECT(log__warnings__regexp(), set, this, FSh, setLogWarningsRegexp)))
00141 return ERROR_BACKTRACE(res);
00142
00143 if (FAILED(res = CONNECT(log__debug__on(), set, this, FSh, setLogDebugEnabled)))
00144 return ERROR_BACKTRACE(res);
00145 if (FAILED(res = CONNECT(log__debug__regexp(), set, this, FSh, setLogDebugRegexp)))
00146 return ERROR_BACKTRACE(res);
00147
00148 if (FAILED(res = CONNECT(ERR(), error, this, FSh, logError)))
00149 return ERROR_BACKTRACE(res);
00150 if (FAILED(res = CONNECT(ERR(), warning, this, FSh, logWarning)))
00151 return ERROR_BACKTRACE(res);
00152 if (FAILED(res = CONNECT(ERR(), debug, this, FSh, logDebug)))
00153 return ERROR_BACKTRACE(res);
00154
00155 return OK;
00156 }
00157
00158 int FSh::dataReady()
00159 {
00160 uint8_t ch;
00161 int res;
00162
00163 if (FAILED(res = _connection->read((char *)&ch, sizeof(ch), 1))) {
00164 ERROR_BACKTRACE(res);
00165 if (FAILED(res = kill()))
00166 ERROR_BACKTRACE(res);
00167 return res;
00168 }
00169
00170 if (ch == IAC) {
00171 int readCnt;
00172
00173 if (FAILED(res = _telnet->parse(&readCnt)))
00174 return ERROR_BACKTRACE(res);
00175 } else
00176 if (FAILED(res = _getLine->pushChar(ch)))
00177 return ERROR_BACKTRACE(res);
00178
00179 return OK;
00180 }
00181
00182 int FSh::die()
00183 {
00184 int res;
00185 if (FAILED(res = CORE()->kill(this)))
00186 return ERROR_BACKTRACE(res);
00187 return OK;
00188 }
00189
00190 int FSh::setColorEnabled(const bool &yes)
00191 {
00192 int res;
00193 if (FAILED(res = String::setColorEnabled(yes)))
00194 return ERROR_BACKTRACE(res);
00195
00196 return OK;
00197 }
00198
00199 int FSh::setLogErrorsEnabled(const bool &yes)
00200 {
00201 _logErrors = yes;
00202 return OK;
00203 }
00204
00205 int FSh::setLogErrorsRegexp(const String &re)
00206 {
00207 if (_logErrorsRe.pattern() != re)
00208 _logErrorsRe = re;
00209 return OK;
00210 }
00211
00212 int FSh::setLogWarningsEnabled(const bool &yes)
00213 {
00214 _logWarnings = yes;
00215 return OK;
00216 }
00217
00218 int FSh::setLogWarningsRegexp(const String &re)
00219 {
00220 if (_logWarningsRe.pattern() != re)
00221 _logWarningsRe = re;
00222 return OK;
00223 }
00224
00225 int FSh::setLogDebugEnabled(const bool &yes)
00226 {
00227 _logDebug = yes;
00228 return OK;
00229 }
00230
00231 int FSh::setLogDebugRegexp(const String &re)
00232 {
00233 if (_logDebugRe.pattern() != re)
00234 _logDebugRe = re;
00235 return OK;
00236 }
00237
00238 int FSh::logError(const String ×tamp, const String &fileName,
00239 const unsigned int lineNum, const String &functionName, const String &msg)
00240 {
00241 if (!_logErrors)
00242 return OK;
00243 #ifdef DEBUG_MODE
00244 String str;
00245 str.sprintf("%s [%s] [file: %s, line: %u, function: %s]: %s%s",
00246 CSTRING(COLOR_ERROR()), CSTRING(timestamp),
00247 CSTRING(fileName), lineNum, CSTRING(functionName), CSTRING(msg),
00248 String::eol());
00249 #else
00250 String str;
00251 str.sprintf("%s: %s%s",
00252 CSTRING(COLOR_ERROR()), CSTRING(msg),
00253 String::eol());
00254 #endif
00255 int res;
00256 if (_logErrorsRe.PartialMatch(str))
00257 if (FAILED(res = FORTH()->printf(CSTRING(str))))
00258 return ERROR_BACKTRACE(res);
00259 return OK;
00260 }
00261
00262 int FSh::logWarning(const String ×tamp, const String &fileName,
00263 const unsigned int lineNum, const String &functionName, const String &msg)
00264 {
00265 if (!_logWarnings)
00266 return OK;
00267 #ifdef DEBUG_MODE
00268 String str;
00269 str.sprintf("%s [%s] [file: %s, line: %u, function: %s]: %s%s",
00270 CSTRING(COLOR_WARNING()), CSTRING(timestamp),
00271 CSTRING(fileName), lineNum, CSTRING(functionName), CSTRING(msg),
00272 String::eol());
00273 #else
00274 String str;
00275 str.sprintf("%s: %s%s",
00276 CSTRING(COLOR_WARNING()), CSTRING(msg),
00277 String::eol());
00278 #endif
00279 int res;
00280 if (_logWarningsRe.PartialMatch(str))
00281 if (FAILED(res = FORTH()->printf(CSTRING(str))))
00282 return ERROR_BACKTRACE(res);
00283 return OK;
00284 }
00285
00286 int FSh::logDebug(const String ×tamp, const String &fileName,
00287 const unsigned int lineNum, const String &functionName, const String &msg)
00288 {
00289 if (!_logDebug)
00290 return OK;
00291 #ifdef DEBUG_MODE
00292 String str;
00293 str.sprintf("%s [%s] [file: %s, line: %u, function: %s]: %s%s",
00294 CSTRING(COLOR_DEBUG()), CSTRING(timestamp),
00295 CSTRING(fileName), lineNum, CSTRING(functionName), CSTRING(msg),
00296 String::eol());
00297 #else
00298 String str;
00299 str.sprintf("%s: %s%s",
00300 CSTRING(COLOR_DEBUG()), CSTRING(msg),
00301 String::eol());
00302 #endif
00303 int res;
00304 if (_logDebugRe.PartialMatch(str))
00305 if (FAILED(res = FORTH()->printf(CSTRING(str))))
00306 return ERROR_BACKTRACE(res);
00307 return OK;
00308 }