📄 tcawmgr.c
字号:
/************************************************************************************************* * The CGI utility of the abstract database API * Copyright (C) 2006-2009 Mikio Hirabayashi * This file is part of Tokyo Cabinet. * Tokyo Cabinet is free software; you can redistribute it and/or modify it under the terms of * the GNU Lesser General Public License as published by the Free Software Foundation; either * version 2.1 of the License or any later version. Tokyo Cabinet is distributed in the hope * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * You should have received a copy of the GNU Lesser General Public License along with Tokyo * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA. *************************************************************************************************/#include <tcutil.h>#include <tcadb.h>#include "myconf.h"#define MINIBNUM 31 // bucket number of map for trivial use#define OUTBUFSIZ (256*1024) // size of the output buffer#define UPLOADMAX (256*1024*1024) // maximum size of the upload data#define DEFSHOWNUM 30 // default number of show result#define FWMMAX 10000 // maximum number of forward matching#define VALWIDTH 80 // maximum width of shown value#define PAGETITLE "Abstract Database Manager" // page title#define DBNAME "casket" // name of the database#define XP(...) tcxstrprintf(obuf, __VA_ARGS__) // syntex sugar of output settingtypedef struct { // type of structure of CGI parameters int action; // kind of the action const char *kbuf; // key buffer int ksiz; // key size const char *vbuf; // value buffer int vsiz; // value size int num; // number per page int page; // number of the page} PARAMS;enum { // enumeration for error codes ACTLIST, // list records ACTLISTVAL, // list records with values ACTPUT, // put a record ACTOUT, // remove a record ACTGET // get a record};/* global variables */const char *g_scriptname; // program name/* function prototypes */int main(int argc, char **argv);static void readparameters(TCMAP *params);static void dolist(PARAMS *params, TCADB *db);static void doget(PARAMS *params, TCADB *db);static void doerror(int code, const char *msg);static void sethtmlheader(PARAMS *params, TCXSTR *obuf, TCADB *db);static void sethtmlfooter(PARAMS *params, TCXSTR *obuf, TCADB *db);static void sethtmlcomform(PARAMS *params, TCXSTR *obuf, TCADB *db);static void sethtmlrecval(const char *kbuf, int ksiz, TCXSTR *obuf, TCADB *db);/* main routine */int main(int argc, char **argv){ g_scriptname = getenv("SCRIPT_NAME"); if(!g_scriptname) g_scriptname = argv[0]; const char *rp = strrchr(g_scriptname, '/'); if(rp) g_scriptname = rp + 1; TCMAP *pmap = tcmapnew2(MINIBNUM); readparameters(pmap); PARAMS params; params.action = ACTLIST; int size; const char *buf = tcmapget(pmap, "action", 6, &size); if(buf) params.action = tcatoix(buf); if(params.action < ACTLIST) params.action = ACTLIST; buf = tcmapget(pmap, "key", 3, &size); if(buf){ params.kbuf = buf; params.ksiz = size; } else { params.kbuf = ""; params.ksiz = 0; } buf = tcmapget(pmap, "value", 5, &size); if(buf){ params.vbuf = buf; params.vsiz = size; } else { params.vbuf = ""; params.vsiz = 0; } if(params.ksiz < 1){ buf = tcmapget(pmap, "value_filename", 14, &size); if(buf){ params.kbuf = buf; params.ksiz = size; } } params.num = 0; buf = tcmapget(pmap, "num", 3, &size); if(buf) params.num = tcatoix(buf); if(params.num < 1) params.num = DEFSHOWNUM; params.page = 1; buf = tcmapget(pmap, "page", 4, &size); if(buf) params.page = tcatoix(buf); if(params.page < 1) params.page = 1; bool wmode; switch(params.action){ case ACTPUT: case ACTOUT: wmode = true; break; default: wmode = false; break; } TCADB *db = tcadbnew(); char path[strlen(DBNAME)+16]; sprintf(path, "%s.tch#mode=%s", DBNAME, wmode ? "w" : "r"); if(!tcadbopen(db, path)){ sprintf(path, "%s.tcb#mode=%s", DBNAME, wmode ? "w" : "r"); if(!tcadbopen(db, path)){ sprintf(path, "%s.tcf#mode=%s", DBNAME, wmode ? "w" : "r"); tcadbopen(db, path); } } if(tcadbsize(db) > 0){ switch(params.action){ case ACTLIST: case ACTLISTVAL: case ACTPUT: case ACTOUT: dolist(¶ms, db); break; case ACTGET: doget(¶ms, db); break; default: doerror(400, "no such action"); break; } } else { doerror(500, "the database file could not be opened"); } tcadbdel(db); tcmapdel(pmap); return 0;}/* read CGI parameters */static void readparameters(TCMAP *params){ int maxlen = UPLOADMAX; char *buf = NULL; int len = 0; const char *rp; if((rp = getenv("REQUEST_METHOD")) != NULL && !strcmp(rp, "POST") && (rp = getenv("CONTENT_LENGTH")) != NULL && (len = tcatoix(rp)) > 0){ if(len > maxlen) len = maxlen; buf = tccalloc(len + 1, 1); if(fread(buf, 1, len, stdin) != len){ tcfree(buf); buf = NULL; } } else if((rp = getenv("QUERY_STRING")) != NULL){ buf = tcstrdup(rp); len = strlen(buf); } if(buf && len > 0){ if((rp = getenv("CONTENT_TYPE")) != NULL && tcstrfwm(rp, "multipart/form-data") && (rp = strstr(rp, "boundary=")) != NULL){ rp += 9; if(*rp == '"') rp++; char bstr[strlen(rp)+1]; strcpy(bstr, rp); char *wp = strchr(bstr, ';'); if(wp) *wp = '\0'; wp = strchr(bstr, '"'); if(wp) *wp = '\0'; TCLIST *parts = tcmimeparts(buf, len, bstr); int pnum = tclistnum(parts); for(int i = 0; i < pnum; i++){ int psiz; const char *part = tclistval(parts, i, &psiz); TCMAP *hmap = tcmapnew2(MINIBNUM); int bsiz; char *body = tcmimebreak(part, psiz, hmap, &bsiz); int nsiz; const char *name = tcmapget(hmap, "NAME", 4, &nsiz); if(name){ tcmapput(params, name, nsiz, body, bsiz); const char *fname = tcmapget2(hmap, "FILENAME"); if(fname){ if(*fname == '/'){ fname = strrchr(fname, '/') + 1; } else if(((*fname >= 'a' && *fname <= 'z') || (*fname >= 'A' && *fname <= 'Z')) && fname[1] == ':' && fname[2] == '\\'){ fname = strrchr(fname, '\\') + 1; } if(*fname != '\0'){ char key[nsiz+10]; sprintf(key, "%s_filename", name); tcmapput2(params, key, fname); } } } tcfree(body); tcmapdel(hmap); } tclistdel(parts); } else { TCLIST *pairs = tcstrsplit(buf, "&;"); int num = tclistnum(pairs); for(int i = 0; i < num; i++){ char *key = tcstrdup(tclistval2(pairs, i)); char *val = strchr(key, '='); if(val){ *(val++) = '\0'; char *dkey = tcurldecode(key, &len); char *dval = tcurldecode(val, &len); tcmapput2(params, dkey, dval); tcfree(dval); tcfree(dkey); } tcfree(key); } tclistdel(pairs); } } tcfree(buf);}/* perform the list action */static void dolist(PARAMS *params, TCADB *db){ printf("Content-Type: text/html\r\n"); printf("\r\n"); TCXSTR *obuf = tcxstrnew3(OUTBUFSIZ); sethtmlheader(params, obuf, db); if(params->action == ACTPUT){ XP("<hr />\n"); if(params->ksiz < 1){ XP("<p>Error: the key should be specified.</p>\n"); } else if(tcadbput(db, params->kbuf, params->ksiz, params->vbuf, params->vsiz)){ XP("<p>Stored successfully!</p>\n"); } else { XP("<p>Error: unknown error.</p>\n"); } params->kbuf = ""; params->ksiz = 0; params->action = ACTLIST; } else if(params->action == ACTOUT){ XP("<hr />\n"); if(params->ksiz < 1){ XP("<p>Error: the key should be specified.</p>\n"); } else if(tcadbout(db, params->kbuf, params->ksiz)){ XP("<p>Removed successfully!</p>\n"); } else if(tcadbvsiz(db, params->kbuf, params->ksiz) >= 0){ XP("<p>Error: unknown error.</p>\n"); } else { XP("<p>Error: no such record.</p>\n"); } params->kbuf = ""; params->ksiz = 0; params->action = ACTLIST;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -