00001
00002
00003
00004
00005
00006
00007
#include "uniclientconn.h"
00008
#include "wvaddr.h"
00009
#include "wvtclstring.h"
00010
#include "strutils.h"
00011
00012
00013
00014
const UniClientConn::CommandInfo UniClientConn::cmdinfos[
00015 UniClientConn::NUM_COMMANDS] = {
00016
00017 {
"noop",
"noop: verify that the connection is active" },
00018 {
"get",
"get <key>: get the value of a key" },
00019 {
"set",
"set <key> <value>: sets the value of a key" },
00020 {
"del",
"del <key>: deletes the key" },
00021 {
"subt",
"subt <key>: enumerates the children of a key" },
00022 {
"hchild",
"hchild <key>: returns whether a key has children" },
00023 {
"quit",
"quit: kills the session nicely" },
00024 {
"help",
"help: returns this help text" },
00025
00026
00027 {
"OK",
"OK <payload>: reply on command success" },
00028 {
"FAIL",
"FAIL <payload>: reply on command failure" },
00029 {
"CHILD",
"CHILD <key> TRUE / FALSE: key has children or not" },
00030 {
"ONEVAL",
"ONEVAL <key> <value>: reply to a get" },
00031
00032
00033 {
"VAL",
"VAL <key> <value>: intermediate reply value of a key" },
00034 {
"TEXT",
"TEXT <text>: intermediate reply of a text message" },
00035
00036
00037 {
"HELLO",
"HELLO <message>: sent by server on connection" },
00038 {
"NOTICE",
"NOTICE <key> <oldval> <newval>: forget key and its children" },
00039 };
00040
00041
00042 UniClientConn::UniClientConn(
IWvStream *_s,
WvStringParm dst) :
00043
WvStreamClone(_s),
00044
log(
WvString("UniConf to %s", dst.isnull() ? *_s->src() :
WvString(dst)),
00045
WvLog::Debug5), closed(false), payloadbuf("")
00046 {
00047 WvIStreamList::globallist.append(
this,
false);
00048
log(
"Opened\n");
00049 }
00050
00051
00052 UniClientConn::~UniClientConn()
00053 {
00054 WvIStreamList::globallist.
unlink(
this);
00055
close();
00056 }
00057
00058
00059 bool UniClientConn::pre_select(SelectInfo &si)
00060 {
00061
if (si.wants.readable && msgbuf.
used())
return true;
00062
return WvStreamClone::pre_select(si);
00063 }
00064
00065
00066 bool UniClientConn::isok()
const
00067
{
00068
return msgbuf.
used() != 0 ||
WvStreamClone::isok();
00069 }
00070
00071
00072 void UniClientConn::close()
00073 {
00074
if (!
closed)
00075 {
00076
closed =
true;
00077
WvStreamClone::close();
00078
log(
"Closed\n");
00079 }
00080 }
00081
00082
00083
WvString UniClientConn::readmsg()
00084 {
00085
WvString word;
00086
while ((word =
wvtcl_getword(msgbuf,
"\r\n",
false)).isnull())
00087 {
00088
char *line = getline(0);
00089
if (line)
00090 {
00091 msgbuf.putstr(line);
00092 msgbuf.
put(
'\n');
00093 }
00094
else
00095 {
00096
if (!
isok())
00097 {
00098
00099 msgbuf.
zap();
00100 }
00101
return WvString::null;
00102 }
00103 }
00104
if (!!word)
00105
log(
"Read: %s\n", word);
00106
return word;
00107 }
00108
00109
00110
void UniClientConn::writemsg(
WvStringParm msg)
00111 {
00112
write(
WvString(
"%s\n", msg));
00113
log(
"Wrote: %s\n", msg);
00114 }
00115
00116
00117 UniClientConn::Command UniClientConn::readcmd()
00118 {
00119
for (;;)
00120 {
00121
WvString msg(readmsg());
00122
if (msg.
isnull())
00123
return NONE;
00124
00125
00126
payloadbuf.
reset(msg);
00127
WvString cmd(
readarg());
00128
if (cmd.
isnull())
00129
return NONE;
00130
00131
for (
int i = 0; i <
NUM_COMMANDS; ++i)
00132
if (strcasecmp(
cmdinfos[i].name, cmd.
cstr()) == 0)
00133
return Command(i);
00134
return INVALID;
00135 }
00136 }
00137
00138
00139 WvString UniClientConn::readarg()
00140 {
00141
return wvtcl_getword(
payloadbuf);
00142 }
00143
00144
00145 void UniClientConn::writecmd(UniClientConn::Command cmd,
WvStringParm msg)
00146 {
00147
if (msg)
00148 writemsg(
WvString(
"%s %s",
cmdinfos[cmd].name, msg));
00149
else
00150 writemsg(
cmdinfos[cmd].name);
00151 }
00152
00153
00154 void UniClientConn::writeok(
WvStringParm payload)
00155 {
00156
writecmd(
REPLY_OK, payload);
00157 }
00158
00159
00160 void UniClientConn::writefail(
WvStringParm payload)
00161 {
00162
writecmd(
REPLY_FAIL, payload);
00163 }
00164
00165
00166 void UniClientConn::writevalue(
const UniConfKey &key,
WvStringParm value)
00167 {
00168
writecmd(
PART_VALUE,
WvString(
"%s %s",
wvtcl_escape(key),
00169
wvtcl_escape(value)));
00170 }
00171
00172
00173 void UniClientConn::writeonevalue(
const UniConfKey &key,
WvStringParm value)
00174 {
00175
writecmd(
REPLY_ONEVAL,
WvString(
"%s %s",
wvtcl_escape(key),
00176
wvtcl_escape(value)));
00177 }
00178
00179
00180 void UniClientConn::writetext(
WvStringParm text)
00181 {
00182
writecmd(
PART_TEXT,
wvtcl_escape(text));
00183 }