/* FIXME */ void sall_command(client c) { dstr res = get_indices(); dstr *fields = NULL; int nfield = 0, i; RTRIM(res); fields = dstr_split_len(res, dstr_length(res), ",", 1, &nfield); for (i = 1; i < nfield; ++i) { dstr pkey = dstr_new(fields[i]); dstr skey = dstr_new(pkey); dlist_t dlist; struct kvd *kvd; table_rwlock_wrlock(subscribers); if ((dlist = table_get_value(subscribers, pkey)) == NULL) { if (NEW(kvd)) { kvd->key = skey; kvd->u.dlist = dlist_new(NULL, NULL); dlist_insert_tail(kvd->u.dlist, c); dlist = dlist_new(cmpkvd, kdfree); dlist_insert_sort(dlist, kvd); table_insert(subscribers, pkey, dlist); } else { add_reply_error(c, "error allocating memory for kvd\r\n"); dstr_free(skey); dstr_free(pkey); } } else { if (NEW(kvd)) { dlist_node_t node; kvd->key = skey; kvd->u.dlist = dlist_new(NULL, NULL); if ((node = dlist_find(dlist, kvd)) == NULL) { dlist_insert_tail(kvd->u.dlist, c); dlist_insert_sort(dlist, kvd); } else { kdfree(kvd); kvd = (struct kvd *)dlist_node_value(node); if (dlist_find(kvd->u.dlist, c) == NULL) dlist_insert_tail(kvd->u.dlist, c); } } else { add_reply_error(c, "error allocating memory for kvd\r\n"); dstr_free(skey); } dstr_free(pkey); } table_rwlock_unlock(subscribers); } dstr_free(res); //-------------------------------------------------------------------------------------------------------------------- // FIXME //-------------------------------------------------------------------------------------------------------------------- }
/* FIXME */ void auth_command(client c) { if (password == NULL) add_reply_error(c, "no password is set"); else if (cmppass(password, c->argv[1]) == 0) { c->authenticated = 1; add_reply_string(c, "OK\r\n", 4); } else { c->authenticated = 0; add_reply_error(c, "invalid password"); } add_reply_string(c, "\r\n", 2); }
/* FIXME */ void u_command(client c) { dstr pkey, skey; dlist_t dlist; if (dstr_length(c->argv[0]) == 1) { add_reply_error(c, "index can't be empty\r\n"); return; } pkey = dstr_new(c->argv[0] + 1); skey = dstr_new(pkey); if (c->argc > 1) { int i; for (i = 1; i < c->argc; ++i) { skey = dstr_cat(skey, ","); skey = dstr_cat(skey, c->argv[i]); } } table_rwlock_wrlock(subscribers); if ((dlist = table_get_value(subscribers, pkey))) { struct kvd *kvd; if (NEW(kvd)) { dlist_node_t node, node2; kvd->key = skey; if ((node = dlist_find(dlist, kvd))) { FREE(kvd); kvd = (struct kvd *)dlist_node_value(node); if ((node2 = dlist_find(kvd->u.dlist, c))) dlist_remove(kvd->u.dlist, node2); if (dlist_length(kvd->u.dlist) == 0) { dlist_remove(dlist, node); kdfree(kvd); } if (dlist_length(dlist) == 0) { table_remove(subscribers, pkey); dlist_free(&dlist); } } else FREE(kvd); } else add_reply_error(c, "error allocating memory for kvd"); } table_rwlock_unlock(subscribers); dstr_free(skey); dstr_free(pkey); add_reply_string(c, "\r\n", 2); }
void process_inbuf(client c) { while (c->inpos > 0) { char *newline; size_t len; if (c->flags & CLIENT_CLOSE_AFTER_REPLY) break; if ((newline = strstr(c->inbuf, "\r\n")) == NULL) { if (c->inpos == sizeof c->inbuf - 1) { add_reply_error(c, "protocol error: too big request\r\n"); c->flags |= CLIENT_CLOSE_AFTER_REPLY; c->inpos = 0; } break; } len = newline - c->inbuf; if (c->argv) FREE(c->argv); /* FIXME */ *newline = '\0'; xcb_log(XCB_LOG_INFO, "Client '%p' issued command '%s'", c, c->inbuf); c->argv = dstr_split_args(c->inbuf, &c->argc); memmove(c->inbuf, c->inbuf + len + 2, sizeof c->inbuf - len - 2); c->inpos -= len + 2; if (c->argc == 0 || process_command(c) == 0) client_reset(c); } }
/* FIXME */ void index_command(client c) { const char *fmt; table_lock(idxfmts); if ((fmt = table_get_value(idxfmts, c->argv[1]))) add_reply_string_format(c, "%s\r\n", fmt); else add_reply_error(c, "format unavailable"); table_unlock(idxfmts); add_reply_string(c, "\r\n", 2); }
/* FIXME */ void uall_command(client c) { dstr res = get_indices(); dstr *fields = NULL; int nfield = 0, i; RTRIM(res); fields = dstr_split_len(res, dstr_length(res), ",", 1, &nfield); for (i = 1; i < nfield; ++i) { dstr pkey = dstr_new(fields[i]); dstr skey = dstr_new(pkey); dlist_t dlist; table_rwlock_wrlock(subscribers); if ((dlist = table_get_value(subscribers, pkey))) { struct kvd *kvd; if (NEW(kvd)) { dlist_node_t node, node2; kvd->key = skey; if ((node = dlist_find(dlist, kvd))) { FREE(kvd); kvd = (struct kvd *)dlist_node_value(node); if ((node2 = dlist_find(kvd->u.dlist, c))) dlist_remove(kvd->u.dlist, node2); if (dlist_length(kvd->u.dlist) == 0) { dlist_remove(dlist, node); kdfree(kvd); } if (dlist_length(dlist) == 0) { table_remove(subscribers, pkey); dlist_free(&dlist); } } else FREE(kvd); } else add_reply_error(c, "error allocating memory for kvd"); } table_rwlock_unlock(subscribers); dstr_free(skey); dstr_free(pkey); } add_reply_string(c, "\r\n", 2); dstr_free(res); }
static void shutdown_command(client c) { if (prepare_for_shutdown() == 0) exit(0); add_reply_error(c, "errors trying to shutdown the server\r\n"); }
/* FIXME */ void s_command(client c) { dstr pkey, skey; int i; dlist_t dlist; struct kvd *kvd; if (dstr_length(c->argv[0]) == 1) { add_reply_error(c, "index can't be empty\r\n"); return; } pkey = dstr_new(c->argv[0] + 1); skey = dstr_new(pkey); //------------------------------------------------------------------------ dstr pre = dstr_new(pkey); dstr rest = dstr_new(""); //------------------------------------------------------------------------ if (c->argc > 1) for (i = 1; i < c->argc; ++i) { skey = dstr_cat(skey, ","); skey = dstr_cat(skey, c->argv[i]); //------------------------------------------------------------------------ rest = dstr_cat(rest,c->argv[i]); //------------------------------------------------------------------------ } /* table_lock(cache); if ((dlist = table_get_value(cache, pkey))) { dlist_iter_t iter = dlist_iter_new(dlist, DLIST_START_HEAD); dlist_node_t node; */ /* FIXME: still has room to improve */ /* while ((node = dlist_next(iter))) { kvd = (struct kvd *)dlist_node_value(node); if (dstr_length(kvd->key) >= dstr_length(skey) && !memcmp(kvd->key, skey, dstr_length(skey))) { dstr *fields = NULL; int nfield = 0; dstr res, contracts = NULL; fields = dstr_split_len(kvd->key, dstr_length(kvd->key), ",", 1, &nfield); res = dstr_new(fields[0]); if (nfield > 1) { contracts = dstr_new(fields[1]); for (i = 2; i < nfield; ++i) { contracts = dstr_cat(contracts, ","); contracts = dstr_cat(contracts, fields[i]); } } dstr_free_tokens(fields, nfield); fields = NULL, nfield = 0; fields = dstr_split_len(kvd->u.value, dstr_length(kvd->u.value), ",", 1, &nfield); res = dstr_cat(res, ","); res = dstr_cat(res, fields[0]); if (contracts) { res = dstr_cat(res, ","); res = dstr_cat(res, contracts); } for (i = 1; i < nfield; ++i) { res = dstr_cat(res, ","); res = dstr_cat(res, fields[i]); } res = dstr_cat(res, "\r\n"); pthread_spin_lock(&c->lock); if (!(c->flags & CLIENT_CLOSE_ASAP)) { if (net_try_write(c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1) { xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", c, strerror(errno)); if (++c->eagcount >= 3) { client_free_async(c); pthread_spin_unlock(&c->lock); dstr_free(contracts); dstr_free(res); dstr_free_tokens(fields, nfield); table_unlock(cache); dstr_free(skey); dstr_free(pkey); return; } } else if (c->eagcount) c->eagcount = 0; } pthread_spin_unlock(&c->lock); dstr_free(contracts); dstr_free(res); dstr_free_tokens(fields, nfield); } } dlist_iter_free(&iter); } table_unlock(cache); */ //--------------------------------------------------------------------------------------------------- /* table_rwlock_wrlock(subscribers); if ((dlist = table_get_value(subscribers, pkey)) == NULL) { if (NEW(kvd)) { kvd->key = skey; kvd->u.dlist = dlist_new(NULL, NULL); dlist_insert_tail(kvd->u.dlist, c); dlist = dlist_new(cmpkvd, kdfree); dlist_insert_sort(dlist, kvd); table_insert(subscribers, pkey, dlist); } else { add_reply_error(c, "error allocating memory for kvd\r\n"); dstr_free(skey); dstr_free(pkey); } } else { if (NEW(kvd)) { dlist_node_t node; kvd->key = skey; kvd->u.dlist = dlist_new(NULL, NULL); if ((node = dlist_find(dlist, kvd)) == NULL) { dlist_insert_tail(kvd->u.dlist, c); dlist_insert_sort(dlist, kvd); } else { kdfree(kvd); kvd = (struct kvd *)dlist_node_value(node); if (dlist_find(kvd->u.dlist, c) == NULL) dlist_insert_tail(kvd->u.dlist, c); } } else { add_reply_error(c, "error allocating memory for kvd\r\n"); dstr_free(skey); } dstr_free(pkey); } table_rwlock_unlock(subscribers); */ //-------------------------------------------------------------------------------------------------------------------- // table_rwlock_wrlock(subscribers_radix); radix_block_insert(pre, ",", subscribers_radix->head); radix_insert(rest, radix_match(pre, subscribers_radix->head, subscribers_radix->head)); pre = dstr_cat(pre,rest); insert_value(pre, c, subscribers_radix->head); dstr_free(pre); dstr_free(rest); // table_rwlock_unlock(subscribers_radix); //--------------------------------------------------------------------------------------------------- }
/* FIXME */ void q_command(client c) { struct tm tm; char *end; char buf[64]; dstr rid; struct crss *crss; if (!persistence) { add_reply_error(c, "database not open\r\n"); return; } if (dstr_length(c->argv[0]) == 1) { add_reply_error(c, "index can't be empty\r\n"); return; } if ((end = strptime(c->argv[3], "%F %T", &tm)) && *end == '\0') c->argv[3] = dstr_cat(c->argv[3], ".000"); else if ((end = strptime(c->argv[3], "%F %R", &tm)) && *end == '\0') c->argv[3] = dstr_cat(c->argv[3], ":00.000"); else { add_reply_error(c, "invalid time format, " "please use 'YYYY-mm-dd HH:MM:SS' or 'YYYY-mm-dd HH:MM'.\r\n"); return; } if ((end = strptime(c->argv[4], "%F %T", &tm)) && *end == '\0') c->argv[4] = dstr_cat(c->argv[4], ".999"); else if ((end = strptime(c->argv[4], "%F %R", &tm)) && *end == '\0') c->argv[4] = dstr_cat(c->argv[4], ":59.999"); else { add_reply_error(c, "invalid time format, " "please use 'YYYY-mm-dd HH:MM:SS' or 'YYYY-mm-dd HH:MM'.\r\n"); return; } snprintf(buf, sizeof buf, "%p,", c); rid = dstr_new(buf); rid = dstr_cat(rid, c->argv[1]); if (rids == NULL) rids = table_new(cmpstr, hashmurmur2, kfree, NULL); table_lock(rids); if ((crss = table_get_value(rids, rid))) { add_reply_error_format(c, "query with rid '%s' already exists\r\n", c->argv[1]); dstr_free(rid); } else if (NEW(crss)) { pthread_t thread; crss->c = c; crss->rid = dstr_new(c->argv[1]); crss->match = dstr_new(c->argv[2]); crss->start = dstr_new(c->argv[0] + 1); crss->start = dstr_cat(crss->start, ","); crss->start = dstr_cat(crss->start, c->argv[3]); crss->stop = dstr_new(c->argv[0] + 1); crss->stop = dstr_cat(crss->stop, ","); crss->stop = dstr_cat(crss->stop, c->argv[4]); crss->cancel = 0; if (pthread_create(&thread, NULL, q_thread, crss) != 0) { add_reply_error(c, strerror(errno)); add_reply_string(c, "\r\n", 2); dstr_free(crss->rid); dstr_free(crss->match); dstr_free(crss->start); dstr_free(crss->stop); FREE(crss); dstr_free(rid); } else { client_incr(crss->c); table_insert(rids, rid, crss); } } else { add_reply_error(c, "error allocating memory for crss\r\n"); dstr_free(rid); } table_unlock(rids); }