/* * input : pname(STR) aname(STR) * return: NORMAL * reply : NULL */ static NEOERR* aic_cmd_app_setsecy(struct queue_entry *q, struct cache *cd, mdb_conn *db) { char *pname, *aname; int pid, aid, upid; NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "pname", pname); REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); pid = hash_string(pname); aid = hash_string(aname); MDB_EXEC(db, NULL, "UPDATE appinfo SET tune=tune & %d WHERE aid=%d OR pid=%d " " RETURNING aid", NULL, ~LCS_TUNE_SECY, pid, pid); upid = aid; err = mdb_get(db, "i", &upid); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "UPDATE appinfo SET tune=tune | %d WHERE aid=%d", NULL, LCS_TUNE_SECY, aid); cache_delf(cd, PREFIX_APPINFO"%d", upid); cache_delf(cd, PREFIX_APPINFO"%d", aid); cache_delf(cd, PREFIX_APPOUSER"%d_0", pid); cache_delf(cd, PREFIX_SECY"%d", pid); return STATUS_OK; }
static NEOERR* aux_cmd_cmtadd(struct queue_entry *q, struct cache *cd, mdb_conn *db) { int type, oid, pid; char *ip, *addr, *author, *content; NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "ip", ip); REQ_GET_PARAM_STR(q->hdfrcv, "addr", addr); REQ_GET_PARAM_STR(q->hdfrcv, "author", author); REQ_GET_PARAM_STR(q->hdfrcv, "content", content); REQ_GET_PARAM_INT(q->hdfrcv, "type", type); REQ_GET_PARAM_INT(q->hdfrcv, "oid", oid); REQ_FETCH_PARAM_INT(q->hdfrcv, "pid", pid); MDB_EXEC(db, NULL, "INSERT INTO comment " " (type, oid, pid, ip, addr, author, content) " " VALUES ($1, $2, $3, $4::varchar(256), " " $5::varchar(256), $6::varchar(256), $7)", "iiissss", type, oid, pid, ip, addr, author, content); cache_delf(cd, PREFIX_CMTAPP"%d:%d_0", type, oid); return STATUS_OK; }
NEOERR* blog_data_del(CGI *cgi, HASH *dbh, HASH *evth, session_t *ses) { mdb_conn *conn = (mdb_conn*)hash_lookup(dbh, "aux"); mevent_t *evt = (mevent_t*)hash_lookup(evth, "aic"); char *aname; int bid, state; NEOERR *err; LPRE_DBOP(cgi->hdf, conn); HDF_GET_INT(cgi->hdf, PRE_QUERY".bid", bid); HDF_GET_INT(cgi->hdf, PRE_QUERY".state", state); APP_CHECK_LOGIN(); if (hdf_get_int_value(evt->hdfrcv, "state", 0) < LCS_ST_ADMIN) return nerr_raise(LERR_LIMIT, "%s wan't be admin", aname); MDB_EXEC(conn, NULL, "UPDATE blog SET state=%d WHERE id=%d AND " " author=$1", "s", state, bid, aname); char command[1024]; snprintf(command, sizeof(command), PATH_PAGER"blg -b %d", bid); mtc_dbg("%s", command); system(command); if (state == BLOG_ST_DEL) { snprintf(command, sizeof(command), "rm -f %s/%d/%d.html", PATH_BLOG, bid%BLOG_SUBDIR_NUM, bid); mtc_dbg("%s", command); system(command); } return STATUS_OK; }
static NEOERR* dyn_cmd_addtrack(struct queue_entry *q, struct cache *cd, mdb_conn *db) { STRING str; string_init(&str); char *aname, *uname, *oname; int aid, uid, oid = 0; NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "uname", uname); REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); REQ_FETCH_PARAM_STR(q->hdfrcv, "oname", oname); uid = hash_string(uname); aid = hash_string(aname); if (oname) oid = hash_string(oname); hdf_set_int_value(q->hdfrcv, "aid", aid); hdf_set_int_value(q->hdfrcv, "uid", uid); hdf_set_int_value(q->hdfrcv, "oid", oid); err = mcs_build_incol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".InsertCol.track"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "INSERT INTO track %s", NULL, str.buf); string_clear(&str); return STATUS_OK; }
static NEOERR* member_after_login(CGI *cgi, HASH *dbh, char *mname) { char tm[LEN_TM_GMT], *p, mmsn[LEN_CK]; mdb_conn *db = hash_lookup(dbh, "main"); NEOERR *err; memset(mmsn, 0x0, sizeof(mmsn)); mstr_rand_string(mmsn, sizeof(mmsn)); mutil_getdatetime_gmt(tm, sizeof(tm), "%A, %d-%b-%Y %T GMT", ONE_WEEK); /* * set cookie */ neos_url_escape(mname, &p, NULL); cgi_cookie_set(cgi, "mname", mname, NULL, SITE_DOMAIN, tm, 1, 0); cgi_cookie_set(cgi, "mname_esc", p, NULL, SITE_DOMAIN, tm, 1, 0); cgi_cookie_set(cgi, "mmsn", mmsn, NULL, SITE_DOMAIN, tm, 1, 0); free(p); hdf_set_value(cgi->hdf, PRE_OUTPUT".mname", mname); hdf_set_value(cgi->hdf, PRE_OUTPUT".mmsn", mmsn); MDB_EXEC(db, NULL, "UPDATE member SET mmsn=$1 WHERE mname=$2", "ss", mmsn, mname); return STATUS_OK; }
/* * input : aname(STR) * return: NORMAL REP_ERR_NREGIST * reply : NULL */ static NEOERR* aic_cmd_appdel(struct queue_entry *q, struct cache *cd, mdb_conn *db) { char *aname; int aid, pid = 0; NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); aid = hash_string(aname); err = aic_cmd_appinfo(q, cd, db); if (err != STATUS_OK) return nerr_pass(err); if (!hdf_get_obj(q->hdfsnd, "state")) return nerr_raise(REP_ERR_NREGIST, "%s not regist", aname); pid = hdf_get_int_value(q->hdfsnd, "pid", 0); MDB_EXEC(db, NULL, "DELETE FROM appinfo WHERE aid=%d;", NULL, aid); cache_delf(cd, PREFIX_APPINFO"%d", aid); if (pid > 0) { cache_delf(cd, PREFIX_APPOUSER"%d_0", pid); } return STATUS_OK; }
static NEOERR* aux_cmd_emailadd(struct aux_entry *e, QueueEntry *q) { STRING str; string_init(&str); char sum[LEN_MD5], *content; NEOERR *err; mdb_conn *db = e->db; REQ_GET_PARAM_STR(q->hdfrcv, "content", content); mstr_md5_str(content, sum); hdf_set_value(q->hdfrcv, "checksum", sum); HDF *node = hdf_get_child(q->hdfrcv, "mto"); insert: if (node) hdf_set_value(q->hdfrcv, "to", hdf_obj_value(node)); err = mdb_build_incol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".InsertCol.email"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "INSERT INTO email %s", NULL, str.buf); string_clear(&str); if (node) { node = hdf_obj_next(node); if (node) goto insert; } return STATUS_OK; }
static NEOERR* aux_cmd_inboxadd(struct aux_entry *e, QueueEntry *q) { STRING str; string_init(&str); NEOERR *err; mdb_conn *db = e->db; HDF *node = hdf_get_child(q->hdfrcv, "mmid"); insert: if (node) hdf_set_value(q->hdfrcv, "mid", hdf_obj_value(node)); err = mdb_build_incol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".InsertCol.inbox"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "INSERT INTO inbox %s", NULL, str.buf); string_clear(&str); if (node) { node = hdf_obj_next(node); if (node) goto insert; } return STATUS_OK; }
NEOERR* blog_data_add(CGI *cgi, HASH *dbh, HASH *evth, session_t *ses) { mdb_conn *conn = (mdb_conn*)hash_lookup(dbh, "aux"); mevent_t *evt = (mevent_t*)hash_lookup(evth, "aic"); char *aname, command[1024]; char *title, *content; int id = 0; NEOERR *err; LPRE_DBOP(cgi->hdf, conn); APP_CHECK_LOGIN(); if (hdf_get_int_value(evt->hdfrcv, "state", 0) < LCS_ST_ADMIN) return nerr_raise(LERR_LIMIT, "%s wan't be admin", aname); HDF_GET_STR(cgi->hdf, PRE_QUERY".title", title); HDF_GET_STR(cgi->hdf, PRE_QUERY".content", content); MDB_EXEC(conn, NULL, "INSERT INTO blog (title, content, author) " " VALUES ($1::varchar(256), $2, " " $3::varchar(256)) RETURNING id", "sss", title, content, aname); err = mdb_get(conn, "i", &id); if (err != STATUS_OK) return nerr_pass(err); snprintf(command, sizeof(command), PATH_PAGER"blg -i 0 -b %d", id); mtc_dbg("%s", command); system(command); return STATUS_OK; }
NEOERR* fill_trackarea(HASH *evth, HASH *dbh) { mdb_conn *conn = (mdb_conn*)hash_lookup(dbh, "dyn"); mevent_t *evt = (mevent_t*)hash_lookup(evth, "place"); HDF *node; hdf_init(&node); char *ip, *aid, *uid, *city, *area; NEOERR *err; LPRE_ALLOP(node, conn, evt); MDB_QUERY_RAW(conn, "track", COL_TRACK, "intime > current_date AND " " area='' GROUP BY aid, uid", NULL); err = mdb_set_rows(node, conn, COL_TRACK, NULL, NULL); if (err != STATUS_OK) return nerr_pass(err); node = hdf_obj_child(node); while (node) { ip = hdf_get_value(node, "ip", NULL); aid = hdf_get_value(node, "aid", "0"); uid = hdf_get_value(node, "uid", "0"); if (ip) { hdf_set_value(evt->hdfsnd, "ip", ip); MEVENT_TRIGGER_NRET(evt, ip, REQ_CMD_PLACEGET, FLAGS_SYNC); city = hdf_get_value(evt->hdfrcv, "0.c", "Mars"); area = city2area(city); MDB_EXEC(conn, NULL, "UPDATE track SET area=$1 WHERE aid=$2 AND uid=$3", "sss", area, aid, uid); } node = hdf_obj_next(node); } return STATUS_OK; }
static NEOERR* aux_cmd_cmtadd(struct aux_entry *e, QueueEntry *q) { STRING str; string_init(&str); int type, oid; NEOERR *err; REQ_GET_PARAM_INT(q->hdfrcv, "type", type); REQ_GET_PARAM_INT(q->hdfrcv, "oid", oid); mdb_conn *db = e->db; struct cache *cd = e->cd; err = mdb_build_incol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".InsertCol.comment"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "INSERT INTO comment %s", NULL, str.buf); string_clear(&str); cache_delf(cd, PREFIX_COMMENT"%d:%d_0", type, oid); return STATUS_OK; }
NEOERR* blog_data_mod(CGI *cgi, HASH *dbh, HASH *evth, session_t *ses) { mdb_conn *conn = (mdb_conn*)hash_lookup(dbh, "aux"); mevent_t *evt = (mevent_t*)hash_lookup(evth, "aic"); char *aname; int bid; NEOERR *err; LPRE_DBOP(cgi->hdf, conn); HDF_GET_INT(cgi->hdf, PRE_QUERY".bid", bid); APP_CHECK_LOGIN(); if (hdf_get_int_value(evt->hdfrcv, "state", 0) < LCS_ST_ADMIN) return nerr_raise(LERR_LIMIT, "%s wan't be admin", aname); STRING str; string_init(&str); err = mcs_build_upcol(hdf_get_obj(cgi->hdf, PRE_QUERY), hdf_get_obj(g_cfg, "Db.UpdateCol.blog"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(conn, NULL, "UPDATE blog SET %s WHERE id=%d AND author=$1", "s", str.buf, bid, aname); string_clear(&str); char command[1024]; snprintf(command, sizeof(command), PATH_PAGER"blg -b %d", bid); mtc_dbg("%s", command); system(command); return STATUS_OK; }
/* * input : uname(STR) aname(STR) * return: NORMAL * reply : NULL */ static NEOERR* aic_cmd_appuserin(struct queue_entry *q, struct cache *cd, mdb_conn *db) { STRING str; string_init(&str); char *aname, *uname; int aid, uid; NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); REQ_GET_PARAM_STR(q->hdfrcv, "uname", uname); aid = hash_string(aname); uid = hash_string(uname); hdf_set_int_value(q->hdfrcv, "uid", uid); hdf_set_int_value(q->hdfrcv, "aid", aid); err = aic_cmd_appusers(q, cd, db); if (err != STATUS_OK) return nerr_pass(err); if (hdf_get_valuef(q->hdfsnd, "userlist.%s.uname", uname)) return STATUS_OK; err = mcs_build_incol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".InsertCol.userinfo"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "INSERT INTO userinfo %s", NULL, str.buf); string_clear(&str); cache_delf(cd, PREFIX_USERLIST"%d", aid); return STATUS_OK; }
static NEOERR* aux_cmd_cmtdel(struct queue_entry *q, struct cache *cd, mdb_conn *db) { int id; NEOERR *err; REQ_GET_PARAM_INT(q->hdfrcv, "id", id); MDB_EXEC(db, NULL, "UPDATE comment SET state=%d WHERE id=%d;", NULL, CMT_ST_DEL, id); return STATUS_OK; }
static NEOERR* aux_cmd_cmtdel(struct aux_entry *e, QueueEntry *q) { int id; NEOERR *err; REQ_GET_PARAM_INT(q->hdfrcv, "id", id); mdb_conn *db = e->db; MDB_EXEC(db, NULL, "UPDATE comment SET statu=%d WHERE id=%d;", NULL, CMT_ST_DEL, id); return STATUS_OK; }
NEOERR* member_logout_data_get(CGI *cgi, HASH *dbh, HASH *evth, session_t *ses) { mdb_conn *db = hash_lookup(dbh, "main"); char *mname; NEOERR *err; MCS_NOT_NULLB(cgi->hdf, db); MEMBER_CHECK_LOGIN(); MDB_EXEC(db, NULL, "UPDATE member SET mmsn='0' WHERE mname=$1", "s", mname); return STATUS_OK; }
/* * input : aname(STR) [asn(STR) masn(STR) email(STR) state(INT)] * return: NORMAL REP_ERR_ALREADYREGIST * reply : NULL */ static NEOERR* aic_cmd_appup(struct queue_entry *q, struct cache *cd, mdb_conn *db) { char *aname; int aid, pid = 0, tune = -1; STRING str; string_init(&str); NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); REQ_FETCH_PARAM_INT(q->hdfrcv, "tune", tune); if (tune != -1) { if (hdf_get_int_value(q->hdfrcv, "tuneop", 0)) { /* set tune bit */ string_appendf(&str, " tune=tune | %d ", tune); } else { /* unset tune bit */ string_appendf(&str, " tune=tune & %d ", ~tune); } } aid = hash_string(aname); err = aic_cmd_appinfo(q, cd, db); if (err != STATUS_OK) return nerr_pass(err); if (!hdf_get_obj(q->hdfsnd, "state")) return nerr_raise(REP_ERR_NREGIST, "%s %d hasn't regist", aname, aid); pid = hdf_get_int_value(q->hdfsnd, "pid", 0); err = mcs_build_upcol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".UpdateCol.appinfo"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "UPDATE appinfo SET %s WHERE aid=%d;", NULL, str.buf, aid); /* TODO memory leak, if exec() failure */ string_clear(&str); cache_delf(cd, PREFIX_APPINFO"%d", aid); if (pid > 0) { cache_delf(cd, PREFIX_APPOUSER"%d_0", pid); } return STATUS_OK; }
static NEOERR* aux_cmd_memoryadd(struct aux_entry *e, QueueEntry *q) { STRING str; string_init(&str); NEOERR *err; mdb_conn *db = e->db; err = mdb_build_incol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".InsertCol.memory"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "INSERT INTO memory %s", NULL, str.buf); string_clear(&str); m_memory_maxid++; return STATUS_OK; }
NEOERR* pos_data_mod(CGI *cgi, HASH *dbh, HASH *evth, session_t *ses) { STRING str; string_init(&str); mdb_conn *db = hash_lookup(dbh, "city"); NEOERR *err; if (!cgi || !cgi->hdf || !db) return nerr_raise(NERR_ASSERT, "paramter null"); int id = hdf_get_int_value(cgi->hdf, PRE_QUERY".id", 0); err = mdb_build_upcol(hdf_get_obj(cgi->hdf, PRE_QUERY), hdf_get_obj(g_cfg, "Db.UpdateCol.city"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "UPDATE city SET %s WHERE id=%d;", NULL, str.buf, id); return STATUS_OK; }
static NEOERR* aic_cmd_app_setrlink(struct queue_entry *q, struct cache *cd, mdb_conn *db) { char *aname, *rlink; NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); REQ_GET_PARAM_STR(q->hdfrcv, "rlink", rlink); err = aic_cmd_appinfo(q, cd, db); if (err != STATUS_OK) return nerr_pass(err); if (!hdf_get_value(q->hdfsnd, "email", NULL)) return nerr_raise(REP_ERR_MISSEMAIL, "%s have no email supplied", aname); MDB_EXEC(db, NULL, "SELECT merge_appreset($1::varchar(256), $2::varchar(256));", "ss", aname, rlink); return STATUS_OK; }
static NEOERR* aux_cmd_mailadd(struct queue_entry *q, struct cache *cd, mdb_conn *db) { STRING str; string_init(&str); char sum[LEN_MD5], *content; NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "content", content); mutil_md5_str(content, sum); hdf_set_value(q->hdfrcv, "checksum", sum); err = mcs_build_incol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".InsertCol.email"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "INSERT INTO email %s", NULL, str.buf); string_clear(&str); return STATUS_OK; }
static NEOERR* aic_cmd_appuserup(struct queue_entry *q, struct cache *cd, mdb_conn *db) { STRING str; string_init(&str); int uid, aid; NEOERR *err; REQ_GET_PARAM_INT(q->hdfrcv, "uid", uid); REQ_GET_PARAM_INT(q->hdfrcv, "aid", aid); err = mcs_build_upcol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".UpdateCol.userinfo"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "UPDATE userinfo SET %s WHERE uid=%d AND aid=%d;", NULL, str.buf, uid, aid); string_clear(&str); cache_delf(cd, PREFIX_USERLIST"%d", aid); return STATUS_OK; }
static NEOERR* aux_cmd_impadd(struct queue_entry *q, struct cache *cd, mdb_conn *db) { STRING str; string_init(&str); NEOERR *err; char *aname; int aid; REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); aid = hash_string(aname); hdf_set_int_value(q->hdfrcv, "aid", aid); err = mcs_build_incol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".InsertCol.improve"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "INSERT INTO improve %s", NULL, str.buf); string_clear(&str); cache_delf(cd, PREFIX_IMP"%d_0", aid); return STATUS_OK; }
static NEOERR* aux_cmd_memorymod(struct aux_entry *e, QueueEntry *q) { STRING str; string_init(&str); int id; NEOERR *err; mdb_conn *db = e->db; struct cache *cd = e->cd; REQ_GET_PARAM_INT(q->hdfrcv, "id", id); err = mdb_build_upcol(q->hdfrcv, hdf_get_obj(g_cfg, CONFIG_PATH".UpdateCol.memory"), &str); if (err != STATUS_OK) return nerr_pass(err); MDB_EXEC(db, NULL, "UPDATE memory SET %s WHERE id=%d;", NULL, str.buf, id); string_clear(&str); cache_delf(cd, PREFIX_MEMORY"%d", id); return STATUS_OK; }
static NEOERR* aic_cmd_appuserout(struct queue_entry *q, struct cache *cd, mdb_conn *db) { char *uname, *aname; int aid; NEOERR *err; REQ_GET_PARAM_STR(q->hdfrcv, "uname", uname); REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); aid = hash_string(aname); err = aic_cmd_appusers(q, cd, db); if (err != STATUS_OK) return nerr_pass(err); if (!hdf_get_valuef(q->hdfsnd, "userlist.%s.uname", uname)) return nerr_raise(REP_ERR_NOTJOIN, "%s not join %s", uname, aname); MDB_EXEC(db, NULL, "DELETE FROM userinfo WHERE uid=%d AND aid=%d;", NULL, hash_string(uname), aid); cache_delf(cd, PREFIX_USERLIST"%d", aid); return STATUS_OK; }
/* * input : aname(STR) asn(STR) masn(STR) email(STR) state(INT) * return: NORMAL REP_ERR_ALREADYREGIST * reply : NULL */ static NEOERR* aic_cmd_appnew(struct queue_entry *q, struct cache *cd, mdb_conn *db) { char *aname, *pname, *asn, *masn, *email; int aid, pid = 0, state; NEOERR *err; REQ_GET_PARAM_INT(q->hdfrcv, "state", state); REQ_GET_PARAM_STR(q->hdfrcv, "aname", aname); REQ_GET_PARAM_STR(q->hdfrcv, "asn", asn); REQ_GET_PARAM_STR(q->hdfrcv, "masn", masn); REQ_GET_PARAM_STR(q->hdfrcv, "email", email); REQ_FETCH_PARAM_STR(q->hdfrcv, "pname", pname); aid = hash_string(aname); if (pname) pid = hash_string(pname); err = aic_cmd_appinfo(q, cd, db); nerr_handle(&err, REP_ERR_NREGIST); if (err != STATUS_OK) return nerr_pass(err); if (hdf_get_obj(q->hdfsnd, "state")) return nerr_raise(REP_ERR_ALREADYREGIST, "%s already regist", aname); MDB_EXEC(db, NULL, "INSERT INTO appinfo (aid, aname, " " pid, asn, masn, email, state) " " VALUES ($1, $2::varchar(256), $3, $4::varchar(256), " " $5::varchar(256), $6::varchar(256), $7);", "isisssi", aid, aname, pid, asn, masn, email, state); cache_delf(cd, PREFIX_APPINFO"%d", aid); if (pid > 0) { cache_delf(cd, PREFIX_APPOUSER"%d_0", pid); } return STATUS_OK; }