summaryrefslogtreecommitdiff
path: root/src/networking.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/networking.c')
-rw-r--r--src/networking.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/src/networking.c b/src/networking.c
index c23939c5c..6e5d32489 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -70,6 +70,7 @@ redisClient *createClient(int fd) {
selectDb(c,0);
c->fd = fd;
+ c->name = NULL;
c->bufpos = 0;
c->querybuf = sdsempty();
c->querybuf_peak = 0;
@@ -377,7 +378,7 @@ void *addDeferredMultiBulkLength(redisClient *c) {
return listLast(c->reply);
}
-/* Populate the length object and try glueing it to the next chunk. */
+/* Populate the length object and try gluing it to the next chunk. */
void setDeferredMultiBulkLength(redisClient *c, void *node, long length) {
listNode *ln = (listNode*)node;
robj *len, *next;
@@ -403,7 +404,7 @@ void setDeferredMultiBulkLength(redisClient *c, void *node, long length) {
asyncCloseClientOnOutputBufferLimitReached(c);
}
-/* Add a duble as a bulk reply */
+/* Add a double as a bulk reply */
void addReplyDouble(redisClient *c, double d) {
char dbuf[128], sbuf[128];
int dlen, slen;
@@ -525,7 +526,7 @@ static void acceptCommonHandler(int fd, int flags) {
}
/* If maxclient directive is set and this is one client more... close the
* connection. Note that we create the client instead to check before
- * for this condition, since now the socket is already set in nonblocking
+ * for this condition, since now the socket is already set in non-blocking
* mode and we can send an error for free using the Kernel I/O */
if (listLength(server.clients) > server.maxclients) {
char *err = "-ERR max number of clients reached\r\n";
@@ -668,6 +669,7 @@ void freeClient(redisClient *c) {
}
/* Release memory */
+ if (c->name) decrRefCount(c->name);
zfree(c->argv);
freeClientMultiState(c);
zfree(c);
@@ -939,7 +941,7 @@ int processMultibulkBuffer(redisClient *c) {
/* Not enough data (+2 == trailing \r\n) */
break;
} else {
- /* Optimization: if the buffer contanins JUST our bulk element
+ /* Optimization: if the buffer contains JUST our bulk element
* instead of creating a new object by *copying* the sds we
* just use the current sds string. */
if (pos == 0 &&
@@ -1123,9 +1125,11 @@ sds getClientInfoString(redisClient *client) {
if (emask & AE_WRITABLE) *p++ = 'w';
*p = '\0';
return sdscatprintf(sdsempty(),
- "addr=%s:%d fd=%d age=%ld idle=%ld flags=%s db=%d sub=%d psub=%d multi=%d qbuf=%lu qbuf-free=%lu obl=%lu oll=%lu omem=%lu events=%s cmd=%s",
+ "addr=%s:%d fd=%d name=%s age=%ld idle=%ld flags=%s db=%d sub=%d psub=%d multi=%d qbuf=%lu qbuf-free=%lu obl=%lu oll=%lu omem=%lu events=%s cmd=%s",
(client->flags & REDIS_UNIX_SOCKET) ? server.unixsocket : ip,
- port,client->fd,
+ port,
+ client->fd,
+ client->name ? (char*)client->name->ptr : "",
(long)(server.unixtime - client->ctime),
(long)(server.unixtime - client->lastinteraction),
flags,
@@ -1190,8 +1194,41 @@ void clientCommand(redisClient *c) {
}
}
addReplyError(c,"No such client");
+ } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) {
+ int j, len = sdslen(c->argv[2]->ptr);
+ char *p = c->argv[2]->ptr;
+
+ /* Setting the client name to an empty string actually removes
+ * the current name. */
+ if (len == 0) {
+ if (c->name) decrRefCount(c->name);
+ c->name = NULL;
+ addReply(c,shared.ok);
+ return;
+ }
+
+ /* Otherwise check if the charset is ok. We need to do this otherwise
+ * CLIENT LIST format will break. You should always be able to
+ * split by space to get the different fields. */
+ for (j = 0; j < len; j++) {
+ if (p[j] < '!' || p[j] > '~') { /* ASCII is assumed. */
+ addReplyError(c,
+ "Client names cannot contain spaces, "
+ "newlines or special characters.");
+ return;
+ }
+ }
+ if (c->name) decrRefCount(c->name);
+ c->name = c->argv[2];
+ incrRefCount(c->name);
+ addReply(c,shared.ok);
+ } else if (!strcasecmp(c->argv[1]->ptr,"getname") && c->argc == 2) {
+ if (c->name)
+ addReplyBulk(c,c->name);
+ else
+ addReply(c,shared.nullbulk);
} else {
- addReplyError(c, "Syntax error, try CLIENT (LIST | KILL ip:port)");
+ addReplyError(c, "Syntax error, try CLIENT (LIST | KILL ip:port | GETNAME | SETNAME connection-name)");
}
}