00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef __GNUG__
00024 # pragma implementation "SimpleTelnetClient.h"
00025 #endif
00026
00027 #include "StrMod/SimpleTelnetClient.h"
00028 #include "StrMod/TelnetChunkerData.h"
00029 #include "StrMod/TelnetChars.h"
00030
00031 namespace strmod {
00032 namespace strmod {
00033
00034 using lcore::U1Byte;
00035
00036 const STR_ClassIdent SimpleTelnetClient::identifier(43UL);
00037 const STR_ClassIdent SimpleTelnetClient::UPlug::identifier(44UL);
00038 const STR_ClassIdent SimpleTelnetClient::SPlug::identifier(45UL);
00039
00040 SimpleTelnetClient::SimpleTelnetClient()
00041 : sent_do_supga_(false), sent_do_echo_(false),
00042 uplugcreated_(false), userplug_(*this),
00043 splugcreated_(false), serverplug_(*this)
00044 {
00045 reset();
00046 }
00047
00048 SimpleTelnetClient::~SimpleTelnetClient()
00049 {
00050 }
00051
00052 bool SimpleTelnetClient::deletePlug(Plug *plug)
00053 {
00054 if ((plug == &userplug_) && uplugcreated_)
00055 {
00056 uplugcreated_ = false;
00057 userplug_.unPlug();
00058 return(true);
00059 }
00060 else if ((plug == &serverplug_) && splugcreated_)
00061 {
00062 splugcreated_ = false;
00063 serverplug_.unPlug();
00064 return(true);
00065 }
00066 return(false);
00067 }
00068
00069 void SimpleTelnetClient::reset()
00070 {
00071 sent_do_supga_ = false;
00072 sent_do_echo_ = false;
00073 if (doProtocol())
00074 {
00075 updatePlugFlags();
00076 }
00077 }
00078
00079 StreamModule::Plug *SimpleTelnetClient::i_MakePlug(int side)
00080 {
00081 assert(((side == ToServer) && !splugcreated_) ||
00082 ((side == ToUser) && !uplugcreated_));
00083
00084 if (side == ToServer)
00085 {
00086 splugcreated_ = true;
00087 return(&serverplug_);
00088 }
00089 else
00090 {
00091 uplugcreated_ = true;
00092 return(&userplug_);
00093 }
00094 }
00095
00096 bool SimpleTelnetClient::doProtocol()
00097 {
00098 const U1Byte echoopt = 1;
00099 const U1Byte supgaopt = 3;
00100
00101 if ((!sent_do_supga_ || !sent_do_echo_) && !toserver_)
00102 {
00103 U1Byte sendopt = echoopt;
00104 if (!sent_do_supga_)
00105 {
00106 sendopt = supgaopt;
00107 sent_do_supga_ = true;
00108 }
00109 else
00110 {
00111 sent_do_echo_ = true;
00112 }
00113
00114 toserver_ = new TelnetChunker::OptionNegotiation(TelnetChars::O_DO, sendopt);
00115 return(true);
00116 }
00117 return(false);
00118 }
00119
00120 void SimpleTelnetClient::updatePlugFlags()
00121 {
00122 setReadableFlagFor(&serverplug_,
00123 (toserver_ || (uplugcreated_
00124 && userplug_.canReadOther())));
00125 setWriteableFlagFor(&userplug_,
00126 (!toserver_ && splugcreated_
00127 && serverplug_.canWriteOther()));
00128
00129 setReadableFlagFor(&userplug_, touser_);
00130 setWriteableFlagFor(&serverplug_, (!touser_ && !toserver_));
00131 }
00132
00133 const StrChunkPtr SimpleTelnetClient::userRead()
00134 {
00135 StrChunkPtr tmp = touser_;
00136 touser_.ReleasePtr();
00137 updatePlugFlags();
00138 return(tmp);
00139 }
00140
00141 void SimpleTelnetClient::serverWrite(const StrChunkPtr &ptr)
00142 {
00143 assert(!toserver_);
00144 if (ptr->AreYouA(TelnetChunker::TelnetData::identifier))
00145 {
00146 if (ptr->AreYouA(TelnetChunker::OptionNegotiation::identifier))
00147 {
00148 StrChunkPtrT<TelnetChunker::OptionNegotiation> optneg =
00149 static_cast<TelnetChunker::OptionNegotiation *>(ptr.GetPtr());
00150
00151 if (optneg->getRequest() == TelnetChars::O_WILL)
00152 {
00153 if ((optneg->getType() != 1) && (optneg->getType() != 3))
00154 {
00155 toserver_ = new TelnetChunker::OptionNegotiation(
00156 TelnetChars::O_DONT, optneg->getType());
00157 }
00158 }
00159 else if (optneg->getRequest() == TelnetChars::O_DO)
00160 {
00161 if (optneg->getType() == 3)
00162 {
00163 toserver_ = new TelnetChunker::OptionNegotiation(
00164 TelnetChars::O_WILL, 3);
00165 }
00166 else
00167 {
00168 toserver_ = new TelnetChunker::OptionNegotiation(
00169 TelnetChars::O_WONT, optneg->getType());
00170 }
00171 }
00172 else if (optneg->getRequest() == TelnetChars::O_DONT)
00173 {
00174 toserver_ = new TelnetChunker::OptionNegotiation(
00175 TelnetChars::O_WONT, optneg->getType());
00176 }
00177
00178
00179
00180
00181
00182 }
00183
00184 }
00185 else
00186 {
00187 touser_ = ptr;
00188 }
00189 updatePlugFlags();
00190 }
00191
00192 const StrChunkPtr SimpleTelnetClient::SPlug::i_Read()
00193 {
00194 SimpleTelnetClient &parent = getParent();
00195 if (parent.toserver_)
00196 {
00197 StrChunkPtr tmp = parent.toserver_;
00198 parent.toserver_.ReleasePtr();
00199 if (!parent.doProtocol())
00200 {
00201 parent.updatePlugFlags();
00202 }
00203 return(tmp);
00204 }
00205 else
00206 {
00207 assert(parent.uplugcreated_);
00208 UPlug &sibling = parent.userplug_;
00209
00210 assert(sibling.pluggedInto());
00211 Plug &readfrom = *(sibling.pluggedInto());
00212
00213 assert(readfrom.isReadable());
00214
00215 setIsReading(readfrom, true);
00216 StrChunkPtr tmp = sibling.readOther();
00217 setIsReading(readfrom, false);
00218 return(tmp);
00219 }
00220 }
00221
00222 void SimpleTelnetClient::UPlug::i_Write(const StrChunkPtr &ptr)
00223 {
00224 SimpleTelnetClient &parent = getParent();
00225 assert(!parent.toserver_ && parent.splugcreated_
00226 && parent.serverplug_.canWriteOther());
00227 assert(getFlagsFrom(*this).canwrite_);
00228
00229 assert(parent.serverplug_.pluggedInto());
00230 Plug &writeto = *(parent.serverplug_.pluggedInto());
00231
00232 if (getFlagsFrom(writeto).iswriting_)
00233 {
00234 parent.toserver_ = ptr;
00235 setWriteable(false);
00236 }
00237 else
00238 {
00239 setIsWriting(writeto, true);
00240 parent.serverplug_.writeOther(ptr);
00241 setIsWriting(writeto, false);
00242 }
00243 }
00244
00245 };
00246 };