WvStreams
uniclientconn.cc
1 /*
2  * Worldvisions Tunnel Vision Software:
3  * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4  *
5  * Manages a connection between the UniConf client and daemon.
6  */
7 #include "uniclientconn.h"
8 #include "wvaddr.h"
9 #include "wvtclstring.h"
10 #include "strutils.h"
11 
12 /***** UniClientConn *****/
13 
14 /* This table is _very_ important!!!
15  *
16  * With UniConf, we promise to never remove or modify the behaviour of
17  * any of the commands listed here. If you want to modify anything,
18  * you'd better just add a new command instead. We keep track of the
19  * version of the UniConf protocol by the number of commands supported
20  * by the server.
21  *
22  * @see UniClientConn::Commands
23  */
24 const UniClientConn::CommandInfo UniClientConn::cmdinfos[
25  UniClientConn::NUM_COMMANDS] = {
26  // requests
27  { "noop", "noop: verify that the connection is active" },
28  { "get", "get <key>: get the value of a key" },
29  { "set", "set <key> <value>: sets the value of a key" },
30  { "setv", "setv <key> <value> ...: set multiple key-value pairs" },
31  { "del", "del <key>: deletes the key" },
32  { "subt", "subt <key> <recurse?>: enumerates the children of a key" },
33  { "hchild", "hchild <key>: returns whether a key has children" },
34  { "commit", "commit: commits changes to disk" },
35  { "refresh", "refresh: refresh contents from disk" },
36  { "quit", "quit: kills the session nicely" },
37  { "help", "help: returns this help text" },
38 
39  // command completion replies
40  { "OK", "OK <payload>: reply on command success" },
41  { "FAIL", "FAIL <payload>: reply on command failure" },
42  { "CHILD", "CHILD <key> TRUE / FALSE: key has children or not" },
43  { "ONEVAL", "ONEVAL <key> <value>: reply to a get" },
44 
45  // partial replies
46  { "VAL", "VAL <key> <value>: intermediate reply value of a key" },
47  { "TEXT", "TEXT <text>: intermediate reply of a text message" },
48 
49  // events
50  { "HELLO", "HELLO <version> <message>: sent by server on connection" },
51  { "NOTICE", "NOTICE <key> <oldval> <newval>: forget key and its children" },
52 };
53 
54 
55 UniClientConn::UniClientConn(IWvStream *_s, WvStringParm dst) :
56  WvStreamClone(_s),
57  log(WvString("UniConf to %s", dst.isnull() && _s->src() ? *_s->src() : WvString(dst)),
58  WvLog::Debug5), closed(false), version(-1), payloadbuf("")
59 {
60  log("Opened\n");
61 }
62 
63 
64 UniClientConn::~UniClientConn()
65 {
66  close();
67 }
68 
69 
71 {
72  if (!closed)
73  {
74  closed = true;
76  log("Closed\n");
77  }
78 }
79 
80 
81 WvString UniClientConn::readmsg()
82 {
83  WvString word;
84  while ((word = wvtcl_getword(msgbuf,
85  WVTCL_NASTY_NEWLINES,
86  false)).isnull())
87  {
88  // use lots of readahead to prevent unnecessary runs through select()
89  // during heavy data transfers.
90  char *line = getline(0, '\n', 20480);
91  if (line)
92  {
93  msgbuf.putstr(line);
94  msgbuf.put('\n');
95  }
96  else
97  {
98  if (!WvStreamClone::isok())
99  {
100  // possibly left some incomplete command behind
101  msgbuf.zap();
102  }
103  return WvString::null;
104  }
105  }
106  if (!!word && 0)
107  log("Read: %s\n", word);
108  return word;
109 }
110 
111 
112 void UniClientConn::writemsg(WvStringParm msg)
113 {
114  write(msg);
115  write("\n");
116  // log("Wrote: %s\n", msg);
117 }
118 
119 
121 {
122  WvString buf;
123  return readcmd(buf);
124 }
125 
127 {
128  WvString msg(readmsg());
129  if (msg.isnull())
130  return NONE;
131 
132  // extract command, leaving the remainder in payloadbuf
133  payloadbuf.reset(msg);
134  command = readarg();
135 
136  if (command.isnull())
137  return NONE;
138 
139  for (int i = 0; i < NUM_COMMANDS; ++i)
140  if (strcasecmp(cmdinfos[i].name, command.cstr()) == 0)
141  return Command(i);
142  return INVALID;
143 }
144 
145 
147 {
148  return wvtcl_getword(payloadbuf);
149 }
150 
151 
153 {
154  if (msg)
155  write(WvString("%s %s\n", cmdinfos[cmd].name, msg));
156  else
157  write(WvString("%s\n", cmdinfos[cmd].name));
158 }
159 
160 
161 void UniClientConn::writeok(WvStringParm payload)
162 {
163  writecmd(REPLY_OK, payload);
164 }
165 
166 
167 void UniClientConn::writefail(WvStringParm payload)
168 {
169  writecmd(REPLY_FAIL, payload);
170 }
171 
172 
173 void UniClientConn::writevalue(const UniConfKey &key, WvStringParm value)
174 {
175  if (value == WvString::null)
177  else
179 }
180 
181 
182 void UniClientConn::writeonevalue(const UniConfKey &key, WvStringParm value)
183 {
185 }
186 
187 
188 void UniClientConn::writetext(WvStringParm text)
189 {
191 }
192 
193 
UniClientConn::REPLY_OK
@ REPLY_OK
Definition: uniclientconn.h:68
wvtcl_getword
WvString wvtcl_getword(WvBuf &buf, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
Get a single tcl word from an input buffer, and return the rest of the buffer untouched.
Definition: wvtclstring.cc:359
UniClientConn::payloadbuf
WvConstStringBuffer payloadbuf
Definition: uniclientconn.h:37
WvStream::write
virtual size_t write(const void *buf, size_t count)
Write data to the stream.
Definition: wvstream.cc:532
UniClientConn::writeok
void writeok(WvStringParm payload="")
Writes a REPLY_OK message.
Definition: uniclientconn.cc:161
UniClientConn::readarg
WvString readarg()
Reads the next argument from the command payload.
Definition: uniclientconn.cc:146
UniClientConn::INVALID
@ INVALID
Definition: uniclientconn.h:52
UniClientConn::REPLY_ONEVAL
@ REPLY_ONEVAL
Definition: uniclientconn.h:71
wvtclstring.h
WvStreamClone::close
virtual void close()
Close this stream.
Definition: wvstreamclone.cc:83
WvBufBase< unsigned char >::putstr
void putstr(WvStringParm str)
Copies a WvString into the buffer, excluding the null-terminator.
Definition: wvbuffer.cc:11
IWvStream
Definition: iwvstream.h:24
UniClientConn::writetext
void writetext(WvStringParm text)
Writes a PART_TEXT message.
Definition: uniclientconn.cc:188
spacecat
WvString spacecat(WvStringParm a, WvStringParm b, char sep=' ', bool onesep=false)
return the string formed by concatenating string 'a' and string 'b' with the 'sep' character between ...
Definition: strutils.cc:114
UniClientConn::NONE
@ NONE
Definition: uniclientconn.h:51
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
WvLog
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's.
Definition: wvlog.h:56
WvFastString::isnull
bool isnull() const
returns true if this string is null
Definition: wvstring.h:290
wvtcl_escape
WvString wvtcl_escape(WvStringParm s, const WvStringMask &nasties=WVTCL_NASTY_SPACES)
tcl-escape a string.
Definition: wvtclstring.cc:128
UniClientConn::PART_VALUE
@ PART_VALUE
Definition: uniclientconn.h:74
WvStream::getline
char * getline(time_t wait_msec=0, char separator='\n', int readahead=1024)
Read up to one line of data from the stream and return a pointer to the internal buffer containing th...
Definition: wvstream.h:175
WvFastString::cstr
const char * cstr() const
return a (const char *) for this string.
Definition: wvstring.h:267
UniConfKey
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition: uniconfkey.h:38
WvStreamClone
WvStreamClone simply forwards all requests to the "cloned" stream.
Definition: wvstreamclone.h:23
WvBufBaseCommonImpl::zap
void zap()
Clears the buffer.
Definition: wvbufbase.h:257
UniClientConn::Command
Command
Definition: uniclientconn.h:49
UniClientConn::CommandInfo
Definition: uniclientconn.h:82
UniClientConn::writefail
void writefail(WvStringParm payload="")
Writes a REPLY_FAIL message.
Definition: uniclientconn.cc:167
UniClientConn::UniClientConn
UniClientConn(IWvStream *_s, WvStringParm dst=WvString::null)
Create a wrapper around the supplied WvStream.
Definition: uniclientconn.cc:55
WvStreamClone::isok
virtual bool isok() const
return true if the stream is actually usable right now
Definition: wvstreamclone.cc:136
UniClientConn::writecmd
void writecmd(Command command, WvStringParm payload=WvString::null)
Writes a command to the connection.
Definition: uniclientconn.cc:152
UniClientConn::readcmd
Command readcmd()
Reads a command from the connection.
Definition: uniclientconn.cc:120
UniClientConn::writeonevalue
void writeonevalue(const UniConfKey &key, WvStringParm value)
Writes a PART_VALUE message.
Definition: uniclientconn.cc:182
UniClientConn::PART_TEXT
@ PART_TEXT
Definition: uniclientconn.h:75
UniClientConn::REPLY_FAIL
@ REPLY_FAIL
Definition: uniclientconn.h:69
UniClientConn::close
virtual void close()
Close this stream.
Definition: uniclientconn.cc:70
WvConstStringBuffer::reset
void reset(WvStringParm _str)
Resets the buffer contents to a new string.
Definition: wvbuffer.cc:111
UniClientConn::writevalue
void writevalue(const UniConfKey &key, WvStringParm value)
Writes a PART_VALUE message.
Definition: uniclientconn.cc:173