static PyObject *tc_TDBQuery_keys(tc_TDBQuery *self) { log_trace("ENTER"); TCLIST *res; PyObject *pylist, *key; const char *pkbuf; int pksiz, i; res = tctdbqrysearch(self->qry); if ( (pylist = PyList_New( (Py_ssize_t)TCLISTNUM(res) )) == NULL ) { tclistdel(res); return NULL; } for(i = 0; i < TCLISTNUM(res); i++){ pkbuf = tclistval(res, i, &pksiz); if ( (key = PyBytes_FromStringAndSize(pkbuf, pksiz)) == NULL ) { Py_CLEAR(pylist); break; } PyList_SET_ITEM(pylist, i, key); } tclistdel(res); return pylist; }
/* * /logout/ * * HTML is in templates/logout.tmpl * * Clean up a users session. Remove their entry from the sessions db and * set the session_id browser cookie to expired. */ static void logout(void) { TCTDB *tdb; TDBQRY *qry; TCLIST *res; int rsize; const char *rbuf; tdb = tctdbnew(); tctdbopen(tdb, SESSION_DB, TDBOWRITER); qry = tctdbqrynew(tdb); tctdbqryaddcond(qry, "session_id", TDBQCSTREQ, user_session.session_id); res = tctdbqrysearch(qry); rbuf = tclistval(res, 0, &rsize); tctdbout(tdb, rbuf, strlen(rbuf)); tclistdel(res); tctdbqrydel(qry); tctdbclose(tdb); tctdbdel(tdb); /* Immediately expire the session cookies */ printf("Set-Cookie: session_id=deleted; " "expires=Thu, 01 Jan 1970 00:00:01 GMT; " "path=/; httponly\r\n"); send_template("templates/logout.tmpl", NULL, NULL); }
/* perform tblread command */ int dotblread(char *name, int rnum){ TCTDB *tdb; int i, j, err, pksiz, rsiz; char pkbuf[RECBUFSIZ]; const char *rbuf; TCMAP *cols; TDBQRY *qry; TCLIST *res; if(showprgr) printf("<Reading Test of Table>\n name=%s rnum=%d\n\n", name, rnum); /* open a database */ tdb = tctdbnew(); tctdbsetxmsiz(tdb, rnum * 80); tctdbsetcache(tdb, -1, rnum / 100, -1); if(!tctdbopen(tdb, name, TDBOREADER)){ fprintf(stderr, "tctdbopen failed\n"); tctdbdel(tdb); return 1; } err = FALSE; /* loop for each record */ for(i = 1; i <= rnum; i++){ /* search for a record */ pksiz = sprintf(pkbuf, "%08d", i); qry = tctdbqrynew(tdb); tctdbqryaddcond(qry, "s", TDBQCSTREQ, pkbuf); res = tctdbqrysearch(qry); for(j = 0; j < tclistnum(res); j++){ rbuf = tclistval(res, j, &rsiz); cols = tctdbget(tdb, rbuf, rsiz); if(cols){ tcmapdel(cols); } else { fprintf(stderr, "tctdbget failed\n"); err = TRUE; break; } } tclistdel(res); tctdbqrydel(qry); /* print progression */ if(showprgr && rnum > 250 && i % (rnum / 250) == 0){ putchar('.'); fflush(stdout); if(i == rnum || i % (rnum / 10) == 0){ printf(" (%08d)\n", i); fflush(stdout); } } } /* close the database */ if(!tctdbclose(tdb)){ fprintf(stderr, "tctdbclose failed\n"); tctdbdel(tdb); return 1; } tctdbdel(tdb); if(showprgr && !err) printf("ok\n\n"); return err ? 1 : 0; }
static PyObject * search(PyObject *self, PyObject *args){ TCTDB *tdb; int ecode, i, rsiz; const char *rbuf, *name; TCMAP *cols; TDBQRY *qry; TCLIST *res; const char *dbname; const char *sfield; const char *stext; const int *max; PyObject* pDict = PyDict_New(); PyObject* pList = PyList_New(0); if (!PyArg_ParseTuple(args, "sssi", &dbname, &sfield, &stext,&max)) return NULL; tdb = tctdbnew(); if(!tctdbopen(tdb, dbname, TDBONOLCK | TDBOREADER)){ ecode = tctdbecode(tdb); fprintf(stderr, "open error: %s\n", tctdberrmsg(ecode)); } qry = tctdbqrynew(tdb); tctdbqryaddcond(qry, sfield, TDBQCSTREQ, stext); tctdbqrysetorder(qry, "savedate", TDBQOSTRDESC); tctdbqrysetlimit(qry, max, 0); res = tctdbqrysearch(qry); for(i = 0; i < tclistnum(res); i++){ rbuf = tclistval(res, i, &rsiz); cols = tctdbget(tdb, rbuf, rsiz); if(cols){ tcmapiterinit(cols); PyDict_SetItemString(pDict, "kid", Py_BuildValue("s",rbuf)); while((name = tcmapiternext2(cols)) != NULL){ PyDict_SetItemString(pDict, name, Py_BuildValue("s", tcmapget2(cols, name))); } PyList_Append(pList,pDict); pDict = PyDict_New(); tcmapdel(cols); } } tclistdel(res); tctdbqrydel(qry); if(!tctdbclose(tdb)){ ecode = tctdbecode(tdb); fprintf(stderr, "close error: %s\n", tctdberrmsg(ecode)); } tctdbdel(tdb); return Py_BuildValue("O",pList); }
/* * This checks if a user is currently logged in. It is called at the start * of each request. * * There are upto three checks performed: * * 1) The session_id cookie from the browser is checked with the stored * session_id generated at login. * 2) The client_id from the browser (currently the user agent string) is * checked against the stored client_id. * * 4) Optionally (enabled by default on the login screen) a check is made * on the requesting ip address against the stored origin_ip that was * used at login. * * If any of these checks fail, the request is denied and the user is * punted to the login screen. */ bool is_logged_in(void) { char session_id[SID_LEN + 1]; TCTDB *tdb; TDBQRY *qry; TCLIST *res; TCMAP *cols; int rsize; const char *rbuf; bool login_ok = false; if (!env_vars.http_cookie) goto out3; snprintf(session_id, sizeof(session_id), "%s", env_vars.http_cookie + 11); tdb = tctdbnew(); tctdbopen(tdb, SESSION_DB, TDBOREADER); qry = tctdbqrynew(tdb); tctdbqryaddcond(qry, "session_id", TDBQCSTREQ, session_id); res = tctdbqrysearch(qry); if (tclistnum(res) == 0) goto out2; rbuf = tclistval(res, 0, &rsize); cols = tctdbget(tdb, rbuf, rsize); tcmapiterinit(cols); /* restrict_ip */ if (atoi(tcmapget2(cols, "restrict_ip")) == 1) { /* origin_ip */ if (strcmp(tcmapget2(cols, "origin_ip"), env_vars.remote_addr) != 0) goto out; } /* client_id */ if (strcmp(tcmapget2(cols, "client_id"), env_vars.http_user_agent) != 0) goto out; /* We got here, all checks are OK */ login_ok = true; out: tcmapdel(cols); out2: tctdbqrydel(qry); tclistdel(res); tctdbclose(tdb); tctdbdel(tdb); out3: return login_ok; }
/* search */ JNIEXPORT jobject JNICALL Java_tokyocabinet_TDBQRY_search (JNIEnv *env, jobject self){ TDBQRY *qry = (TDBQRY *)(intptr_t)(*env)->GetLongField(env, self, tdbqry_fid_ptr); TCLIST *tkeys = tctdbqrysearch(qry); jclass clslist = (*env)->FindClass(env, CLSARRAYLIST); jmethodID midinit = (*env)->GetMethodID(env, clslist, "<init>", "()V"); jobject pkeys = (*env)->NewObject(env, clslist, midinit); jmethodID midadd = (*env)->GetMethodID(env, clslist, "add", "(L" CLSOBJECT ";)Z"); for(int i = 0; i < tclistnum(tkeys); i++){ int ksiz; const char *kbuf = tclistval(tkeys, i, &ksiz); jbyteArray pkey = (*env)->NewByteArray(env, ksiz); (*env)->SetByteArrayRegion(env, pkey, 0, ksiz, (jbyte *)kbuf); (*env)->CallVoidMethod(env, pkeys, midadd, pkey); (*env)->DeleteLocalRef(env, pkey); } tclistdel(tkeys); return pkeys; }
/* perform search command */ static int procsearch(const char *path, TCLIST *conds, const char *oname, const char *otype, int omode, int max, int skip, bool pv, bool px, bool kw, bool ph, int bt, bool rm, const char *mtype){ TCTDB *tdb = tctdbnew(); if(g_dbgfd != INVALID_HANDLE_VALUE) tctdbsetdbgfd(tdb, g_dbgfd); if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb); if(!tctdbopen(tdb, path, (rm ? TDBOWRITER : TDBOREADER) | omode)){ printerr(tdb); tctdbdel(tdb); return 1; } bool err = false; TDBQRY *qry = tctdbqrynew(tdb); int cnum = tclistnum(conds); for(int i = 0; i < cnum - 2; i += 3){ const char *name = tclistval2(conds, i); const char *opstr = tclistval2(conds, i + 1); const char *expr = tclistval2(conds, i + 2); int op = tctdbqrystrtocondop(opstr); if(op >= 0) tctdbqryaddcond(qry, name, op, expr); } if(oname){ int type = tctdbqrystrtoordertype(otype); if(type >= 0) tctdbqrysetorder(qry, oname, type); } tctdbqrysetlimit(qry, max, skip); if(rm){ double stime = tctime(); if(!tctdbqrysearchout(qry)){ printerr(tdb); err = true; } double etime = tctime(); if(ph){ TCLIST *hints = tcstrsplit(tctdbqryhint(qry), "\n"); int hnum = tclistnum(hints); for(int i = 0; i < hnum; i++){ const char *hint = tclistval2(hints, i); if(*hint == '\0') continue; printf("\t:::: %s\n", hint); } tclistdel(hints); printf("\t:::: number of records: %d\n", tctdbqrycount(qry)); printf("\t:::: elapsed time: %.5f\n", etime - stime); } } else if(bt > 0){ double sum = 0; for(int i = 1; i <= bt; i++){ double stime = tctime(); TCLIST *res = tctdbqrysearch(qry); double etime = tctime(); tclistdel(res); printf("%d: %.5f sec.\n", i, etime - stime); sum += etime - stime; } printf("----\n"); printf("total: %.5f sec. (%.5f s/q = %.5f q/s)\n", sum, sum / bt, bt / sum); } else { double stime = tctime(); TCLIST *res; TCLIST *hints; int count; int mtnum = mtype ? tctdbmetastrtosettype(mtype) : -1; if(mtnum >= 0){ TDBQRY *qrys[cnum/3+1]; int qnum = 0; for(int i = 0; i < cnum - 2; i += 3){ const char *name = tclistval2(conds, i); const char *opstr = tclistval2(conds, i + 1); const char *expr = tclistval2(conds, i + 2); int op = tctdbqrystrtocondop(opstr); if(op >= 0){ qrys[qnum] = tctdbqrynew(tdb); tctdbqryaddcond(qrys[qnum], name, op, expr); if(oname){ int type = tctdbqrystrtoordertype(otype); if(type >= 0) tctdbqrysetorder(qrys[qnum], oname, type); } tctdbqrysetlimit(qrys[qnum], max, skip); qnum++; } } res = tctdbmetasearch(qrys, qnum, mtnum); hints = qnum > 0 ? tcstrsplit(tctdbqryhint(qrys[0]), "\n") : tclistnew2(1); count = qnum > 0 ? tctdbqrycount(qrys[0]) : 0; for(int i = 0; i < qnum; i++){ tctdbqrydel(qrys[i]); } } else { res = tctdbqrysearch(qry); hints = tcstrsplit(tctdbqryhint(qry), "\n"); count = tctdbqrycount(qry); } double etime = tctime(); if(max < 0) max = INT_MAX; int rnum = tclistnum(res); for(int i = 0; i < rnum && max > 0; i++){ int pksiz; const char *pkbuf = tclistval(res, i, &pksiz); if(kw){ TCMAP *cols = tctdbget(tdb, pkbuf, pksiz); if(cols){ TCLIST *texts = tctdbqrykwic(qry, cols, NULL, 16, TCKWMUTAB); int tnum = tclistnum(texts); for(int j = 0; j < tnum && max > 0; j++){ int tsiz; const char *text = tclistval(texts, j, &tsiz); printdata(pkbuf, pksiz, px); putchar('\t'); printdata(text, tsiz, px); putchar('\n'); max--; } tclistdel(texts); tcmapdel(cols); } } else { printdata(pkbuf, pksiz, px); if(pv){ TCMAP *cols = tctdbget(tdb, pkbuf, pksiz); if(cols){ tcmapiterinit(cols); const char *kbuf; int ksiz; while((kbuf = tcmapiternext(cols, &ksiz)) != NULL){ int vsiz; const char *vbuf = tcmapiterval(kbuf, &vsiz); putchar('\t'); printdata(kbuf, ksiz, px); putchar('\t'); printdata(vbuf, vsiz, px); } tcmapdel(cols); } } putchar('\n'); max--; } } if(ph){ int hnum = tclistnum(hints); for(int i = 0; i < hnum; i++){ const char *hint = tclistval2(hints, i); if(*hint == '\0') continue; printf("\t:::: %s\n", hint); } printf("\t:::: number of records: %d\n", count); printf("\t:::: elapsed time: %.5f\n", etime - stime); } tclistdel(hints); tclistdel(res); } tctdbqrydel(qry); if(!tctdbclose(tdb)){ if(!err) printerr(tdb); err = true; } tctdbdel(tdb); return err ? 1 : 0; }
/* * Sets up the user_session structure. This contains various bits of * information pertaining to the users session. */ void set_user_session(void) { TCTDB *tdb; TDBQRY *qry; TCLIST *res; TCMAP *cols; int rsize; int primary_key_size; char pkbuf[256]; char session_id[SID_LEN + 1]; char login_at[21]; char last_seen[21]; char uid[11]; char sid[21]; char restrict_ip[2]; char capabilities[4]; char user_hdr[1025]; char *xss_string; const char *rbuf; /* * Don't assume the order we get the cookies back is the * same order as we sent them. */ if (strncmp(env_vars.http_cookie, "session_id", 10) == 0) snprintf(session_id, sizeof(session_id), "%s", env_vars.http_cookie + 11); else snprintf(session_id, sizeof(session_id), "%s", env_vars.http_cookie + 88); tdb = tctdbnew(); tctdbopen(tdb, SESSION_DB, TDBOREADER | TDBOWRITER); /* Get the users stored session */ qry = tctdbqrynew(tdb); tctdbqryaddcond(qry, "session_id", TDBQCSTREQ, session_id); res = tctdbqrysearch(qry); rbuf = tclistval(res, 0, &rsize); cols = tctdbget(tdb, rbuf, rsize); tcmapiterinit(cols); memset(&user_session, 0, sizeof(user_session)); snprintf(user_session.tenant, sizeof(user_session.tenant), "%s", tcmapget2(cols, "tenant")); user_session.sid = strtoull(tcmapget2(cols, "sid"), NULL, 10); user_session.uid = atoi(tcmapget2(cols, "uid")); user_session.username = strdup(tcmapget2(cols, "username")); user_session.name = strdup(tcmapget2(cols, "name")); user_session.login_at = atol(tcmapget2(cols, "login_at")); user_session.last_seen = time(NULL); snprintf(user_session.origin_ip, sizeof(user_session.origin_ip), "%s", tcmapget2(cols, "origin_ip")); user_session.client_id = strdup(tcmapget2(cols, "client_id")); snprintf(user_session.session_id, sizeof(user_session.session_id), "%s", tcmapget2(cols, "session_id")); snprintf(user_session.csrf_token, sizeof(user_session.csrf_token), "%s", tcmapget2(cols, "csrf_token")); user_session.restrict_ip = atoi(tcmapget2(cols, "restrict_ip")); user_session.capabilities = atoi(tcmapget2(cols, "capabilities")); tcmapdel(cols); tclistdel(res); tctdbqrydel(qry); /* * Set the user header banner, which displays the users name, uid and * whether they are an Approver and or Admin. */ xss_string = xss_safe_string(user_session.name); snprintf(user_hdr, sizeof(user_hdr), "<big><big> %s</big></big><small>" "<span class = \"lighter\"> (%d) </span>" "</small>", xss_string, user_session.uid); free(xss_string); if (IS_APPROVER() && IS_ADMIN()) strncat(user_hdr, "<span class = \"t_red\">(Approver / Admin)" "</span>", 1024 - strlen(user_hdr)); else if (IS_APPROVER()) strncat(user_hdr, "<span class = \"t_red\">(Approver)" "</span>", 1024 - strlen(user_hdr)); else if (IS_ADMIN()) strncat(user_hdr, "<span class = \"t_red\">(Admin)" "</span>", 1024 - strlen(user_hdr)); strncat(user_hdr, " ", 1024 - strlen(user_hdr)); user_session.user_hdr = strdup(user_hdr); /* * We want to update the last_seen timestamp in the users session. * This entails removing the old session first then storing the new * updated session. */ qry = tctdbqrynew(tdb); tctdbqryaddcond(qry, "session_id", TDBQCSTREQ, session_id); res = tctdbqrysearch(qry); rbuf = tclistval(res, 0, &rsize); tctdbout(tdb, rbuf, strlen(rbuf)); tclistdel(res); tctdbqrydel(qry); primary_key_size = sprintf(pkbuf, "%ld", (long)tctdbgenuid(tdb)); snprintf(login_at, sizeof(login_at), "%ld", user_session.login_at); snprintf(last_seen, sizeof(last_seen), "%ld", user_session.last_seen); snprintf(uid, sizeof(uid), "%u", user_session.uid); snprintf(sid, sizeof(sid), "%llu", user_session.sid); snprintf(restrict_ip, sizeof(restrict_ip), "%d", user_session.restrict_ip); snprintf(capabilities, sizeof(capabilities), "%d", user_session.capabilities); cols = tcmapnew3("tenant", user_session.tenant, "sid", sid, "uid", uid, "username", user_session.username, "name", user_session.name, "login_at", login_at, "last_seen", last_seen, "origin_ip", user_session.origin_ip, "client_id", user_session.client_id, "session_id", user_session.session_id, "csrf_token", user_session.csrf_token, "restrict_ip", restrict_ip, "capabilities", capabilities, NULL); tctdbput(tdb, pkbuf, primary_key_size, cols); tcmapdel(cols); tctdbclose(tdb); tctdbdel(tdb); }