Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

uniclientgen.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * UniClientGen is a UniConfGen for retrieving data from the 00006 * UniConfDaemon. 00007 */ 00008 #include "uniclientgen.h" 00009 #include "wvtclstring.h" 00010 #include "wvtcp.h" 00011 #include "wvaddr.h" 00012 #include "wvresolver.h" 00013 #include "wvmoniker.h" 00014 #include "wvsslstream.h" 00015 00016 #ifndef _WIN32 00017 #include "wvunixsocket.h" 00018 static UniConfGen *unixcreator(WvStringParm s, IObject *, void *) 00019 { 00020 return new UniClientGen(new WvUnixConn(s)); 00021 } 00022 static WvMoniker<UniConfGen> unixreg("unix", unixcreator); 00023 #endif 00024 00025 static UniConfGen *tcpcreator(WvStringParm _s, IObject *, void *) 00026 { 00027 WvString s(_s); 00028 char *cptr = s.edit(); 00029 00030 if (!strchr(cptr, ':')) // no default port 00031 s.append(":%s", DEFAULT_UNICONF_DAEMON_TCP_PORT); 00032 00033 return new UniClientGen(new WvTCPConn(s), _s); 00034 } 00035 00036 static UniConfGen *sslcreator(WvStringParm _s, IObject *, void *) 00037 { 00038 WvString s(_s); 00039 char *cptr = s.edit(); 00040 00041 if (!strchr(cptr, ':')) // no default port 00042 s.append(":%s", DEFAULT_UNICONF_DAEMON_SSL_PORT); 00043 00044 return new UniClientGen(new WvSSLStream(new WvTCPConn(s), NULL, true), _s); 00045 } 00046 00047 // if 'obj' is a WvStream, build the uniconf connection around that; 00048 // otherwise, create a new WvStream using 's' as the wvstream moniker. 00049 static UniConfGen *wvstreamcreator(WvStringParm s, IObject *obj, void *) 00050 { 00051 IWvStream *stream = NULL; 00052 if (obj) 00053 stream = mutate<IWvStream>(obj); 00054 if (!stream) 00055 stream = wvcreate<IWvStream>(s); 00056 return new UniClientGen(stream); 00057 } 00058 00059 static WvMoniker<UniConfGen> tcpreg("tcp", tcpcreator); 00060 static WvMoniker<UniConfGen> sslreg("ssl", sslcreator); 00061 static WvMoniker<UniConfGen> wvstreamreg("wvstream", wvstreamcreator); 00062 00063 00064 00065 /***** UniClientGen *****/ 00066 00067 UniClientGen::UniClientGen(IWvStream *stream, WvStringParm dst) : 00068 conn(NULL), log(WvString("UniClientGen to %s", 00069 dst.isnull() ? *stream->src() : WvString(dst))), 00070 cmdinprogress(false), cmdsuccess(false) 00071 { 00072 conn = new UniClientConn(stream, dst); 00073 conn->setcallback(WvStreamCallback(this, 00074 &UniClientGen::conncallback), NULL); 00075 00076 deltastream.setcallback(WvStreamCallback(this, &UniClientGen::deltacb), 0); 00077 WvIStreamList::globallist.append(&deltastream, false); 00078 } 00079 00080 00081 UniClientGen::~UniClientGen() 00082 { 00083 WvIStreamList::globallist.unlink(&deltastream); 00084 00085 conn->writecmd(UniClientConn::REQ_QUIT, ""); 00086 delete conn; 00087 } 00088 00089 00090 bool UniClientGen::isok() 00091 { 00092 return (conn && conn->isok()); 00093 } 00094 00095 00096 bool UniClientGen::refresh() 00097 { 00098 // FIXME: This should make sure everything in the queue has been flushed 00099 return true; 00100 } 00101 00102 00103 WvString UniClientGen::get(const UniConfKey &key) 00104 { 00105 WvString value; 00106 conn->writecmd(UniClientConn::REQ_GET, wvtcl_escape(key)); 00107 00108 if (do_select()) 00109 { 00110 if (result_key == key) 00111 value = result; 00112 else 00113 seterror("Error: server sent wrong key pair."); 00114 } 00115 return value; 00116 } 00117 00118 00119 void UniClientGen::set(const UniConfKey &key, WvStringParm newvalue) 00120 { 00121 //set_queue.append(new WvString(key), true); 00122 hold_delta(); 00123 00124 if (newvalue.isnull()) 00125 conn->writecmd(UniClientConn::REQ_REMOVE, wvtcl_escape(key)); 00126 else 00127 conn->writecmd(UniClientConn::REQ_SET, 00128 WvString("%s %s", wvtcl_escape(key), wvtcl_escape(newvalue))); 00129 00130 unhold_delta(); 00131 } 00132 00133 00134 bool UniClientGen::haschildren(const UniConfKey &key) 00135 { 00136 conn->writecmd(UniClientConn::REQ_HASCHILDREN, wvtcl_escape(key)); 00137 00138 if (do_select()) 00139 { 00140 if (result_key == key && result == "TRUE") 00141 return true; 00142 } 00143 00144 return false; 00145 } 00146 00147 00148 UniClientGen::Iter *UniClientGen::iterator(const UniConfKey &key) 00149 { 00150 result_list = new WvStringList(); 00151 conn->writecmd(UniClientConn::REQ_SUBTREE, wvtcl_escape(key)); 00152 00153 if (do_select()) 00154 return new RemoteKeyIter(result_list); 00155 00156 delete result_list; 00157 return new UniConfGen::NullIter(); 00158 } 00159 00160 00161 void UniClientGen::conncallback(WvStream &stream, void *userdata) 00162 { 00163 if (conn->alarm_was_ticking) 00164 { 00165 // command response took too long! 00166 log(WvLog::Error, "Command timeout; connection closed.\n"); 00167 cmdinprogress = false; 00168 cmdsuccess = false; 00169 conn->close(); 00170 00171 return; 00172 } 00173 00174 UniClientConn::Command command = conn->readcmd(); 00175 00176 switch (command) 00177 { 00178 case UniClientConn::NONE: 00179 // do nothing 00180 break; 00181 00182 case UniClientConn::REPLY_OK: 00183 cmdsuccess = true; 00184 cmdinprogress = false; 00185 break; 00186 00187 case UniClientConn::REPLY_FAIL: 00188 result_key = WvString::null; 00189 cmdsuccess = false; 00190 cmdinprogress = false; 00191 break; 00192 00193 case UniClientConn::REPLY_CHILD: 00194 { 00195 WvString key(wvtcl_getword(conn->payloadbuf, " ")); 00196 WvString value(wvtcl_getword(conn->payloadbuf, " ")); 00197 00198 if (!key.isnull() && !value.isnull()) 00199 { 00200 result_key = key; 00201 result = value; 00202 cmdsuccess = true; 00203 } 00204 cmdinprogress = false; 00205 break; 00206 00207 } 00208 00209 case UniClientConn::REPLY_ONEVAL: 00210 { 00211 WvString key(wvtcl_getword(conn->payloadbuf, " ")); 00212 WvString value(wvtcl_getword(conn->payloadbuf, " ")); 00213 00214 if (!key.isnull() && !value.isnull()) 00215 { 00216 result_key = key; 00217 result = value; 00218 cmdsuccess = true; 00219 } 00220 00221 cmdinprogress = false; 00222 break; 00223 } 00224 00225 case UniClientConn::PART_VALUE: 00226 { 00227 WvString key(wvtcl_getword(conn->payloadbuf, " ")); 00228 WvString value(wvtcl_getword(conn->payloadbuf, " ")); 00229 00230 if (!key.isnull() && !value.isnull()) 00231 { 00232 if (result_list) 00233 result_list->append(new WvString(key), true); 00234 } 00235 break; 00236 } 00237 00238 case UniClientConn::EVENT_HELLO: 00239 { 00240 WvString server(wvtcl_getword(conn->payloadbuf, " ")); 00241 00242 if (server.isnull() || strncmp(server, "UniConf", 7)) 00243 { 00244 // wrong type of server! 00245 log(WvLog::Error, "Connected to a non-UniConf serer!\n"); 00246 00247 cmdinprogress = false; 00248 cmdsuccess = false; 00249 conn->close(); 00250 } 00251 break; 00252 } 00253 00254 case UniClientConn::EVENT_NOTICE: 00255 { 00256 WvString key(wvtcl_getword(conn->payloadbuf, " ")); 00257 WvString value(wvtcl_getword(conn->payloadbuf, " ")); 00258 clientdelta(key, value); 00259 } 00260 00261 default: 00262 // discard unrecognized commands 00263 break; 00264 } 00265 } 00266 00267 00268 bool UniClientGen::do_select() 00269 { 00270 cmdinprogress = true; 00271 cmdsuccess = false; 00272 00273 conn->alarm(TIMEOUT); 00274 while (conn->isok() && cmdinprogress) 00275 { 00276 if (conn->select(-1)) 00277 { 00278 conn->callback(); 00279 conn->alarm(TIMEOUT); 00280 } 00281 } 00282 conn->alarm(-1); 00283 00284 if (!cmdsuccess) 00285 seterror("Error: server timed out on response."); 00286 00287 return cmdsuccess; 00288 } 00289 00290 00291 00292 /***** UniClientGen::RemoteKeyIter *****/ 00293 00294 void UniClientGen::RemoteKeyIter::rewind() 00295 { 00296 i.rewind(); 00297 } 00298 00299 00300 bool UniClientGen::RemoteKeyIter::next() 00301 { 00302 return i.next(); 00303 } 00304 00305 00306 UniConfKey UniClientGen::RemoteKeyIter::key() const 00307 { 00308 return UniConfKey(*i).last(); 00309 } 00310 00311 void UniClientGen::clientdelta(const UniConfKey &key, WvStringParm value) 00312 { 00313 deltas.append(new UniConfPair(key, value), true); 00314 deltastream.alarm(0); 00315 } 00316 00317 void UniClientGen::deltacb(WvStream &, void *) 00318 { 00319 hold_delta(); 00320 UniConfPairList::Iter i(deltas); 00321 00322 for (i.rewind(); i.next(); ) 00323 delta(i->key(), i->value()); 00324 00325 deltas.zap(); 00326 unhold_delta(); 00327 }

Generated on Tue Oct 5 01:09:19 2004 for WvStreams by doxygen 1.3.7