コード例 #1
0
ファイル: otjt.c プロジェクト: kingiol/cmoon
int tjt_add_image(CGI *cgi, mdb_conn *conn, session_t *ses)
{
    unsigned char hash[LEN_MD5];
    int ret;

    FILE *fp = cgi_filehandle(cgi, "imagename");

    PRE_DBOP(cgi->hdf, conn);

    if (fp == NULL) {
        mtc_err("input file named: imagename not found");
        return RET_RBTOP_INPUTE;
    }

    /* TODO image don't divide into tjt_x currently */
    ret = lutil_image_accept(fp, "tjt", hash);
    if (ret != RET_RBTOP_OK) {
        mtc_err("accept image failure %d", ret);
        return ret;
    }

    hdf_set_valuef(cgi->hdf, PRE_OUTPUT".imageurl=%s/%s/%s/%s.jpg",
                   IMG_DOMAIN, IMG_PATH, IMG_ORI, hash);
    hdf_set_valuef(cgi->hdf, PRE_OUTPUT".imagename=%s.jpg", hash);
    return RET_RBTOP_OK;
}
コード例 #2
0
ファイル: ofile.c プロジェクト: kingiol/cmoon
int file_get_info_by_id(mdb_conn *conn, int id, char *url, int pid, file_t **file)
{
    char mmckey[LEN_MMC_KEY];
    file_t *fl;
    size_t datalen;
    char *buf;
    int ret;
    
    if (id < 0 && (url == NULL || pid < 0))    return RET_RBTOP_INPUTE;

    if (id <= 0)
        snprintf(mmckey, LEN_MMC_KEY, "%s.%d.%s", PRE_MMC_FILE, pid, url);
    else
        snprintf(mmckey, LEN_MMC_KEY, "%s.%d", PRE_MMC_FILE, id);
    buf = mmc_get(mmckey, &datalen, 0);
    if (buf == NULL || datalen < sizeof(file_t)) {
        if (buf != NULL && datalen < sizeof(file_t)) {
            mtc_warn("get %d %d.%s info error from mmc %d",
                     id, pid, url, datalen);
        }
        if (mdb_get_errcode(conn) != MDB_ERR_NONE) {
            mtc_err("conn err %s", mdb_get_errmsg(conn));
            return RET_RBTOP_INPUTE;
        }
        fl = file_new();
        if (fl == NULL) return RET_RBTOP_MEMALLOCE;
        if (id <= 0) {
            LDB_QUERY_RAW(conn, "fileinfo", FILE_QUERY_COL,
                          "pid=%d AND name=$1", "s", pid, url);
        } else {
            LDB_QUERY_RAW(conn, "fileinfo", FILE_QUERY_COL,
                          "id=%d", NULL, id);
        }
        ret = FILE_GET_RAW(conn, fl);
        if (ret != MDB_ERR_NONE) {
            mtc_err("get %d %d.%s info failure from db %s",
                    id, pid, url, mdb_get_errmsg(conn));
            if (ret == MDB_ERR_NORESULT)
                return RET_RBTOP_NEXIST;
            return RET_RBTOP_SELECTE;
        } else {
            file_pack(fl, &buf, &datalen);
            mmc_store(MMC_OP_SET, mmckey, (void*)buf, datalen, ONE_HOUR, 0);
        }
    } else {
        ret = file_unpack(buf, datalen, &fl, NULL);
        if (ret != RET_RBTOP_OK) {
            mtc_err("assembly file from mmc error");
            return RET_RBTOP_MMCERR;
        }
    }
    free(buf);
    *file = fl;
    return RET_RBTOP_OK;
}
コード例 #3
0
ファイル: test.c プロジェクト: bigmaliang/sam
int main(int argc, char **argv, char **envp)
{
	CGI *cgi = NULL;
	NEOERR *err;
	mdb_conn *conn = NULL;

	char *s, *u, *p, *r, *jcbk;

	mtc_init("test");
	mconfig_parse_file(SITE_CONFIG, &g_cfg);

	if (mdb_init(&conn, DB_DSN) != MDB_ERR_NONE) {
		mtc_err("init db error %s", mdb_get_errmsg(conn));
		printf("Content-Type: text/html; charset=UTF-8\r\n\r\n");
		printf("{errcode: %d}", SAM_ERR_INIT);
		return 1;
	}
	
	err = cgi_init(&cgi, NULL);
	if (err != STATUS_OK) {
		mtc_err("init cgi error");
		printf("Content-Type: text/html; charset=UTF-8\r\n\r\n");
		printf("初始化错误");
		return 1;
	}
	err = cgi_parse(cgi);
	if (err != STATUS_OK) {
		mtc_err("parse cgi error");
		hdf_set_value(cgi->hdf, PRE_OUTPUT".errmsg", "初始化出错");
		goto finish;
	}

	u = hdf_get_value(cgi->hdf, PRE_COOKIE".samuser", NULL);
	s = hdf_get_value(cgi->hdf, PRE_COOKIE".samkey", NULL);
	if (s && u) {
		if (user_has_login(conn, u, s)) {
			hdf_set_copy(cgi->hdf, PRE_OUTPUT".samuser", PRE_COOKIE".samuser");
			hdf_set_copy(cgi->hdf, PRE_OUTPUT".samkey", PRE_COOKIE".samkey");
			hdf_set_value(cgi->hdf, PRE_OUTPUT".rcode", "1");
			goto finish;
		}
	}

	hdf_set_value(cgi->hdf, PRE_OUTPUT".rcode", "2");

finish:
	cgi_display(cgi, F_TPL_TEST);
	cgi_destroy(&cgi);
	mdb_destroy(conn);
	return 0;
}
コード例 #4
0
ファイル: moc_base.c プロジェクト: bigclean/moc
static EventEntry* base_init_driver(void)
{
    struct base_entry *e = calloc(1, sizeof(struct base_entry));
    if (e == NULL) return NULL;
    NEOERR *err;

    e->base.name = (unsigned char*)strdup(PLUGIN_NAME);
    e->base.ksize = strlen(PLUGIN_NAME);
    e->base.process_driver = base_process_driver;
    e->base.stop_driver = base_stop_driver;
    //moc_add_timer(&e->base.timers, 60, true, hint_timer_up_term, NULL);

    //char *s = hdf_get_value(g_cfg, CONFIG_PATH".dbsn", NULL);
    //err = mdb_init(&e->db, s);
    //JUMP_NOK(err, error);

    err = base_info_init(&m_base);
    JUMP_NOK(err, error);
    
    e->cd = cache_create(hdf_get_int_value(g_cfg, CONFIG_PATH".numobjs", 1024), 0);
    if (e->cd == NULL) {
        mtc_err("init cache failure");
        goto error;
    }
    
    return (EventEntry*)e;
    
error:
    if (e->base.name) free(e->base.name);
    if (e->db) mdb_destroy(e->db);
    if (e->cd) cache_free(e->cd);
    free(e);
    return NULL;
}
コード例 #5
0
ファイル: lutil.c プロジェクト: kingiol/cmoon
int lutil_fill_layout_by_file(mdb_conn *conn, file_t *file, HDF *hdf)
{
    ULIST *files = NULL;
    file_t *fl;
    int ret, errsn;

    PRE_DBOP(hdf, conn);
    if (file == NULL)
        return RET_RBTOP_INPUTE;

    hdf_set_value(hdf, PRE_LAYOUT".title", file->remark);

    ret = file_get_infos_by_uri(conn, file->uri, &files, &errsn);
    if (ret != RET_RBTOP_OK) {
        mtc_err("get files's infos by uri %s failure %d",
                file->uri, errsn);
        return ret;
    }

    MLIST_ITERATE(files, fl) {
        hdf_set_valuef(hdf, "%s.crumbs.%d.name=%s",
                       PRE_LAYOUT, t_rsv_i, fl->remark);
        if (fl->reqtype == CGI_REQ_AJAX) {
            hdf_set_valuef(hdf, "%s.crumbs.%d.href=%s.html",
                           PRE_LAYOUT, t_rsv_i, fl->uri);
        } else {
            hdf_set_valuef(hdf, "%s.crumbs.%d.href=%s",
                           PRE_LAYOUT, t_rsv_i, fl->uri);
        }
    }
コード例 #6
0
ファイル: mmg.c プロジェクト: pombredanne/cmoon
char* mmg_get_valuef(mmg_conn *db, char *dsn, char *key, int skip, char *qfmt, ...)
{
    HDF *tmpnode; hdf_init(&tmpnode);
    char *val, *querys, sels[256];
    va_list ap;
    NEOERR *err;

    va_start(ap, qfmt);
    querys = vsprintf_alloc(qfmt, ap);
    va_end(ap);
    if (!querys) {
        mtc_err("Unable to allocate mem for query string");
        return NULL;
    }

    snprintf(sels, sizeof(sels), "{'%s': 1}", key);
    err = mmg_prepare(db, MMG_FLAG_EMPTY, skip, 1, NULL, sels, querys);
    RETURN_V_NOK(err, NULL);

    err = mmg_query(db, dsn, NULL, tmpnode);
    RETURN_V_NOK(err, NULL);

    err = hdf_get_copy(tmpnode, key, &val, NULL);
    RETURN_V_NOK(err, NULL);

    hdf_destroy(&tmpnode);
    SAFE_FREE(querys);

    return val;
}
コード例 #7
0
ファイル: levt.c プロジェクト: bigmaliang/dida
NEOERR* levt_init(HASH **evth)
{
    mevent_t *evt;
    char *ename;
    HDF *node;
    HASH *levth;
    NEOERR *err;

    node = hdf_get_obj(g_cfg, "Mevent");
    if (!node) return nerr_raise(NERR_ASSERT, "Mevent config not found");

    err = hash_init(&levth, hash_str_hash, hash_str_comp, hash_str_free);
    if (err != STATUS_OK) return nerr_pass(err);

    node = hdf_obj_child(node);
    while (node != NULL) {
        ename = hdf_obj_value(node);
        evt = mevent_init_plugin(ename);
        if (evt) {
            mtc_dbg("event %s init ok", ename);
            hash_insert(levth, (void*)strdup(ename), (void*)evt);
        } else {
            mtc_err("event %s init failure", ename);
        }

        node = hdf_obj_next(node);
    }

    *evth = levth;
    return STATUS_OK;
}
コード例 #8
0
ファイル: ouser.c プロジェクト: bigmaliang/sam
char* user_login_auth(mdb_conn *conn, char *uid, char *pass)
{
	if (!conn || !uid || !pass) return NULL;

	char *p, *r;
	int ret, x;
	
	mdb_exec(conn, NULL, "SELECT password from account WHERE userid=$1;", "s", uid);
	if (mdb_get(conn, "s", &p) == MDB_ERR_NONE) {
		if (!strcmp(p, pass)) {
			
			r = calloc(1, LEN_SKEY+1);
			for (x = 0; x < LEN_SKEY; x++) {
				r[x] = (char)(65 + neo_rand(90-65));
			}
			r[x] = '\0';

			ret = mdb_exec(conn, NULL, "UPDATE account SET skey='$1' WHERE "
						   " userid=$2;", "ss", r, uid);
			if (ret != MDB_ERR_NONE) {
				mtc_err("exec failure %s", mdb_get_errmsg(conn));
				free(r);
				return NULL;
			}
			return r;
		}
	}

	return NULL;
}
コード例 #9
0
ファイル: lerr.c プロジェクト: kingiol/cmoon
void lerr_opfinish_json(NEOERR *err, HDF *hdf)
{
    if (err == STATUS_OK) {
        hdf_set_value(hdf, PRE_SUCCESS, "1");
        return;
    }
    
    hdf_remove_tree(hdf, PRE_SUCCESS);
    
    char buf[1024], errname[128];
    NEOERR *neede = mcs_err_valid(err);
    if (!neede) neede = err;
    snprintf(buf, sizeof(buf), "%s:%d %s",
             neede->file, neede->lineno,
             _lookup_errname(neede, errname, sizeof(errname)));
    /* set PRE_ERRXXX with the most recently err */
    if (!hdf_get_obj(hdf, PRE_ERRMSG)) {
        hdf_set_value(hdf, PRE_ERRMSG, buf);
    }
    hdf_set_int_value(hdf, PRE_ERRCODE, neede->error);

    STRING str; string_init(&str);
    nerr_error_traceback(err, &str);
    mtc_err("%s", str.buf);
    hdf_set_value(hdf, PRE_ERRTRACE, str.buf);
    nerr_ignore(&err);
    string_clear(&str);
}
コード例 #10
0
ファイル: otjt.c プロジェクト: kingiol/cmoon
int tjt_add_atom(HDF *hdf, mdb_conn *conn, session_t *ses)
{
    PRE_DBOP(hdf, conn);

    int aid, fid, uid;
    char *img, *exp, tbl[LEN_TB];
    int ret;

    uid = ses->member->uin;
    aid = ses->file->aid;
    fid = ses->file->id;
    img = hdf_get_value(hdf, PRE_QUERY".img", "");
    exp = hdf_get_value(hdf, PRE_QUERY".exp", "");

    snprintf(tbl, sizeof(tbl), "tjt_%d", aid);

    ret = MDATA_SET(conn, EVT_PLUGIN_TJT, NULL, FLAGS_NONE,
                    "INSERT INTO %s (fid, uid, img, exp) "
                    " VALUES (%d, %d, $1, $2)", "ss",
                    tbl, fid, uid, img, exp);
    if (ret != MDB_ERR_NONE) {
        mtc_err("add file err %s", mdb_get_errmsg(conn));
        return RET_RBTOP_INSERTE;
    }
    tjt_refresh_info(aid, fid);

    return RET_RBTOP_OK;
}
コード例 #11
0
ファイル: lerr.c プロジェクト: bigml/mgate
void lerr_opfinish_json(NEOERR *err, HDF *hdf)
{
    if (err == STATUS_OK) {
        hdf_set_value(hdf, PRE_SUCCESS, "1");
        mcs_set_int_attr(hdf, PRE_SUCCESS, "type", CNODE_TYPE_INT);
        return;
    }

    hdf_remove_tree(hdf, PRE_SUCCESS);

    NEOERR *neede = mcs_err_valid(err);
    /* set PRE_ERRXXX with the most recently err */
    mcs_set_int_value_with_type(hdf, PRE_ERRCODE, neede->error, CNODE_TYPE_INT);
    if (!hdf_get_obj(hdf, PRE_ERRMSG)) {
        hdf_set_valuef(hdf, "%s=%s:%d %s",
                       PRE_ERRMSG, neede->file, neede->lineno, neede->desc);
    }

    STRING str; string_init(&str);
    nerr_error_traceback(err, &str);
    mtc_err("%s", str.buf);
    hdf_set_value(hdf, PRE_ERRTRACE, str.buf);
    nerr_ignore(&err);
    string_clear(&str);
}
コード例 #12
0
ファイル: lutil.c プロジェクト: kingiol/cmoon
void* lutil_get_data_handler(void *lib, CGI *cgi)
{
    char *file, *tp;
    char hname[_POSIX_PATH_MAX];
    void *res;

    /*
     * how to distinguish /music/zhangwei and /member/zhangwei ?
     * /music/zhangwei may be use music_data_xxx
     * /member/zhangwei may be use member_data_xxx
     */
    file = hdf_get_value(cgi->hdf, PRE_RSV_DATAER, NULL);
    if (file == NULL) {
        mtc_err("%s not found", PRE_RSV_DATAER);
        return NULL;
    }
    
    switch (CGI_REQ_METHOD(cgi)) {
        case CGI_REQ_GET:
            snprintf(hname, sizeof(hname), "%s_data_get", file);
            break;
        case CGI_REQ_POST:
            snprintf(hname, sizeof(hname), "%s_data_mod", file);
            break;
        case CGI_REQ_PUT:
            snprintf(hname, sizeof(hname), "%s_data_add", file);
            break;
        case CGI_REQ_DEL:
            snprintf(hname, sizeof(hname), "%s_data_del", file);
            break;
        default:
            mtc_err("op not support");
            return NULL;
    }

    res = dlsym(lib, hname);
    if ((tp = dlerror()) != NULL) {
        mtc_err("%s", tp);
        return NULL;
    } else
        mtc_info("%s found for data handler", hname);
    return res;
}
コード例 #13
0
ファイル: ofile.c プロジェクト: kingiol/cmoon
int file_get_files(HDF *hdf, mdb_conn *conn, session_t *ses)
{
    PRE_DBOP(hdf, conn);

    int ret, cnt = 0;
    char tok[LEN_MD];
    int count, offset, uin, pid;
    ULIST *gnode;
    gnode_t *node;
    member_t *mb;
    file_t *fl;

    pid = hdf_get_int_value(hdf, PRE_QUERY".pid", 1);

    //sprintf(tok, "pid=%d", pid);
    //mmisc_set_count(hdf, conn, "fileinfo", tok);
    mmisc_get_offset(hdf, &count, &offset);

    if (member_has_login(hdf, conn, ses) != RET_RBTOP_OK) {
        return RET_RBTOP_NOTLOGIN;
    }

    if (!member_has_gmode(ses->member, GROUP_MODE_SENIOR, GROUP_STAT_OK)) {
        mtc_warn("%d attemped to list sys-file", ses->member->uin);
        return RET_RBTOP_LIMITE;
    }

    ret = member_get_group(ses->member, GROUP_MODE_SENIOR, GROUP_STAT_OK, &gnode);
    if (ret != RET_RBTOP_OK) {
        mtc_err("get %d %d failure", ses->member->uin, GROUP_MODE_SENIOR);
        return ret;
    }

    MLIST_ITERATE(gnode, node) {
        ret = file_get_info_by_id(conn, node->gid, NULL, -1, &fl);
        if (ret != RET_RBTOP_OK) {
            mtc_err("get %d info failure", node->gid);
            continue;
        }
        sprintf(tok, "%s.files.%d", PRE_OUTPUT, cnt++);
        file_item2hdf(fl, tok, hdf);
        file_del(fl);
    }
コード例 #14
0
ファイル: ofile.c プロジェクト: kingiol/cmoon
int file_get_info_by_uri(mdb_conn *conn, char *uri, file_t **file)
{
    file_t *fl;
    size_t datalen;
    char *buf;
    int ret;
    
    if (uri == NULL) return RET_RBTOP_INPUTE;

    buf = mmc_getf(&datalen, 0, PRE_MMC_FILE".%s", uri);
    if (buf == NULL || datalen < sizeof(file_t)) {
        if (buf != NULL && datalen < sizeof(file_t)) {
            mtc_warn("get %s info error from mmc %d", uri, datalen);
        }
        if (mdb_get_errcode(conn) != MDB_ERR_NONE) {
            mtc_err("conn err %s", mdb_get_errmsg(conn));
            return RET_RBTOP_INPUTE;
        }
        fl = file_new();
        if (fl == NULL) return RET_RBTOP_MEMALLOCE;
        LDB_QUERY_RAW(conn, "fileinfo", FILE_QUERY_COL, "uri=$1", "s", uri);
        ret = FILE_GET_RAW(conn, fl);
        if (ret != MDB_ERR_NONE) {
            mtc_err("get %s info failure from db %s", uri, mdb_get_errmsg(conn));
            if (ret == MDB_ERR_NORESULT)
                return RET_RBTOP_NEXIST;
            return RET_RBTOP_SELECTE;
        } else {
            file_pack(fl, &buf, &datalen);
            mmc_storef(MMC_OP_SET, (void*)buf, datalen, ONE_HOUR, 0,
                       PRE_MMC_FILE".%s", uri);
        }
    } else {
        ret = file_unpack(buf, datalen, &fl, NULL);
        if (ret != RET_RBTOP_OK) {
            mtc_err("assembly file from mmc error");
            return RET_RBTOP_MMCERR;
        }
    }
    free(buf);
    *file = fl;
    return RET_RBTOP_OK;
}
コード例 #15
0
ファイル: lcs.c プロジェクト: kingiol/cmoon
int lcs_set_layout_infoa(HDF *hdf, const char *title, anchor_t *crumbs,
                         anchor_t *g_nav, int navnum)
{
    int ret;
    NEOERR *err;
    int i;

    hdf_set_value(hdf, "hdf.loadpaths.0", PATH_FRT_TPL);
    hdf_set_value(hdf, PRE_LAYOUT".title", title);
    //ret = mcs_set_login_info(hdf);

    char key[LEN_ST];
    HDF *node;
    for (i = 0; i < navnum; i++) {
        sprintf(key, "%s.tabs.%d", PRE_LAYOUT, i);
        err = hdf_get_node(hdf, key, &node);
        if (err != STATUS_OK) {
            mtc_err("create %dst node for layout.tabs failure");
            continue;
        }
        if (!strcmp(g_nav[i].name, crumbs[0].name)) {
            hdf_set_value(node, "class", "selected");
        }
        hdf_set_value(node, "href", g_nav[i].href);
        hdf_set_value(node, "name", g_nav[i].name);
    }

    i = -1;
    while (strcmp(crumbs[++i].name, "")) {
        sprintf(key, "%s.crumbs.%d", PRE_LAYOUT, i);
        err = hdf_get_node(hdf, key, &node);
        if (err != STATUS_OK) {
            mtc_err("create %dst node for layout.crumbs failure");
            continue;
        }
        hdf_set_value(node, "href", crumbs[i].href);
        hdf_set_value(node, "name", crumbs[i].name);
    }
    
    return ret;
}
コード例 #16
0
ファイル: exp.c プロジェクト: bigml/emoon
SDL_Texture* create_texture(char *file)
{
    char fname[1024];
    snprintf(fname, sizeof(fname), "studyres/%s", file);
    
    SDL_Texture *tex = IMG_LoadTexture(m_render, fname);
	if (!tex) {
        mtc_err("SDL_LoadBMP Error: %s", SDL_GetError());
		return NULL;
	}

    return tex;
}
コード例 #17
0
ファイル: ofile.c プロジェクト: kingiol/cmoon
void file_refresh_info(mdb_conn *conn, int id, char *url, int pid)
{
    file_t *fl;
    int ret;

    ret = file_get_info_by_id(conn, id, url, pid, &fl);
    if (ret != RET_RBTOP_OK) {
        mtc_err("get info failure %d %s %d", id, url, pid);
        return;
    }
    file_refresh_me(fl);
    file_del(fl);
}
コード例 #18
0
ファイル: lutil.c プロジェクト: kingiol/cmoon
void* lutil_get_data_handler(void *lib, CGI *cgi, session_t *ses)
{
    char *hname, *tp;
    void *res;

    hname = ses->dataer;
    res = dlsym(lib, hname);
    if ((tp = dlerror()) != NULL) {
        mtc_err("%s", tp);
        return NULL;
    } else
        mtc_info("%s found for data handler", hname);
    return res;
}
コード例 #19
0
ファイル: mevent_city.c プロジェクト: adderly/cmoon
/*
 * ip2place part
 */
static char* gb2utf8(char *s)
{
    if (!s || !*s) return NULL;

    if (!cv || cv == (iconv_t)-1) cv = iconv_open("UTF-8", "GB2312");
    if (cv == (iconv_t)-1) {
        mtc_err("init conv error %s", strerror(errno));
        return NULL;
    }

    size_t len = strlen(s), ulen;
    ulen = len*2;
    char *utf8 = calloc(1, ulen);
    char *us = utf8;
    
    if (iconv (cv, &s, &len, &utf8, &ulen) == -1) {
        mtc_err("conv error");
        free(us);
        return NULL;
    }
    
    //iconv_close(cv);
    return us;
}
コード例 #20
0
ファイル: mscli.c プロジェクト: bigclean/moc
/*
 * queue
 */
struct msqueue* msqueue_create()
{
    struct msqueue *q;

    q = calloc(1, sizeof(struct msqueue));
    if (!q) {
        mtc_err("alloc msqueue");
        return NULL;
    }

    q->size = 0;
    q->top = NULL;
    q->bottom = NULL;

    return q;
}
コード例 #21
0
ファイル: exp.c プロジェクト: bigml/emoon
SDL_Texture* create_texture_str(char *msg, SDL_Color color, int fontsize)
{
    TTF_Font *font = TTF_OpenFont("studyres/a.ttf", fontsize);
    if (!font) {
        mtc_err("create font error %s", TTF_GetError());
        return NULL;
    }

    SDL_Surface *sur = TTF_RenderText_Blended(font, msg, color);
    SDL_Texture *tex = SDL_CreateTextureFromSurface(m_render2, sur);

    SDL_FreeSurface(sur);
    TTF_CloseFont(font);

    return tex;
}
コード例 #22
0
ファイル: mscli.c プロジェクト: bigclean/moc
struct msqueue_entry* msqueue_entry_create()
{
    struct msqueue_entry *e = calloc(1, sizeof(struct msqueue_entry));
    if (!e) {
        mtc_err("out of memory");
        return NULL;
    }

    e->ename = NULL;
    e->cmd = NULL;

    hdf_init(&e->hdfrcv);
    hdf_init(&e->hdfsnd);
    
    e->prev = NULL;

    return e;
}
コード例 #23
0
ファイル: mmg.c プロジェクト: pombredanne/cmoon
int mmg_get_int_valuef(mmg_conn *db, char *dsn, char *key, int skip, int limit,
                       char *qfmt, ...)
{
    HDF *tmpnode; hdf_init(&tmpnode);
    char *querys, sels[256];
    int val;
    va_list ap;
    HDF *node;
    NEOERR *err;

    va_start(ap, qfmt);
    querys = vsprintf_alloc(qfmt, ap);
    va_end(ap);
    if (!querys) {
        mtc_err("Unable to allocate mem for query string");
        return 0;
    }

    snprintf(sels, sizeof(sels), "{'%s': 1}", key);
    err = mmg_prepare(db, MMG_FLAG_EMPTY, skip, limit, NULL, sels, querys);
    RETURN_V_NOK(err, 0);

    err = mmg_query(db, dsn, NULL, tmpnode);
    RETURN_V_NOK(err, 0);

    val = 0;
    
    if(hdf_get_valuef(tmpnode, "0.%s", key)) {
        node = hdf_obj_child(tmpnode);
        while (node) {
            val += hdf_get_int_value(node, key, 0);
            
            node = hdf_obj_next(node);
        }
    } else {
        val = hdf_get_int_value(tmpnode, key, 0);
    }

    hdf_destroy(&tmpnode);
    SAFE_FREE(querys);

    return val;
}
コード例 #24
0
ファイル: mevent_aux.c プロジェクト: kingiol/cmoon
static EventEntry* aux_init_driver(void)
{
    struct aux_entry *e = calloc(1, sizeof(struct aux_entry));
    if (e == NULL) return NULL;
    NEOERR *err;

    e->base.name = (unsigned char*)strdup(PLUGIN_NAME);
    e->base.ksize = strlen(PLUGIN_NAME);
    e->base.process_driver = aux_process_driver;
    e->base.stop_driver = aux_stop_driver;
    //mevent_add_timer(&e->base.timers, 60, true, hint_timer_up_term);

    char *s = hdf_get_value(g_cfg, CONFIG_PATH".dbsn", NULL);
    err = mdb_init(&e->db, s);
    JUMP_NOK(err, error);
    
    e->cd = cache_create(hdf_get_int_value(g_cfg, CONFIG_PATH".numobjs", 1024), 0);
    if (e->cd == NULL) {
        wlog("init cache failure");
        goto error;
    }

    err = mdb_exec(e->db, NULL, "SELECT id from memory ORDER BY id DESC LIMIT 1", NULL);
    JUMP_NOK(err, error);
    err = mdb_get(e->db, "i", &m_memory_maxid);
    if (nerr_handle(&err, NERR_NOT_FOUND)) {
        mtc_err("table memory empty");
        wlog("table memory empty");
    }
    JUMP_NOK(err, error);
    
    return (EventEntry*)e;
    
error:
    if (e->base.name) free(e->base.name);
    if (e->db) mdb_destroy(e->db);
    if (e->cd) cache_free(e->cd);
    free(e);
    return NULL;
}
コード例 #25
0
ファイル: mevent_city.c プロジェクト: adderly/cmoon
static NEOERR* city_cmd_ip(struct city_entry *e, QueueEntry *q)
{
	unsigned char *val = NULL; size_t vsize = 0;
    char *ip, *c, *a, *s;
	NEOERR *err;

    struct cache *cd = e->cd;
    
    REQ_GET_PARAM_STR(q->hdfrcv, "ip", ip);

    if (cache_getf(cd, &val, &vsize, PREFIX_CITY"%s", ip)) {
        unpack_hdf(val, vsize, &q->hdfsnd);
    } else {
        if (!ip2place(q->hdfsnd, ip, NULL))
            return nerr_raise(NERR_ASSERT, "%s not ip", ip);
        c = hdf_get_value(q->hdfsnd, "c", NULL);
        a = hdf_get_value(q->hdfsnd, "a", NULL);
        s = strstr(c, "省");
        if (!s) s = strstr(c, "区");
        if (s) {
            s += 3;
            char tok[64] = {0};
            strncpy(tok, c, s-c);
            hdf_set_value(q->hdfrcv, "p", tok);
            hdf_set_value(q->hdfrcv, "c", s);
        } else {
            mtc_err("%s doesn't contain 省/区(%s)", c, a);
            hdf_set_value(q->hdfrcv, "c", c);
        }
        err = city_cmd_s(e, q);
        if (err != STATUS_OK) return nerr_pass(err);

        CACHE_HDF(q->hdfsnd, CITY_CC_SEC, PREFIX_CITY"%s", ip);
    }
    
    return STATUS_OK;
}
コード例 #26
0
ファイル: tcp.c プロジェクト: bigclean/moc
int tcp_srv_send(moc_srv *srv, unsigned char *buf, size_t bsize, moc_arg *arg)
{
    ssize_t rv;
    uint32_t len;

    len = htonl(bsize);
    memcpy(buf, (const void *) &len, 4);

    if (srv->fd <= 0) {
        bool reconnectok = true;
        /*
         * connect closed by server, catched by:
         * 1. el_routine() on #ifdef EVENTLOOP or
         * 2. moc_trigger() on #ifndef EVENTLOP
         */
        mtc_dbg("connection closed, reconnect");

        /*
         * although we reconnect to the server agin,
         * but we haven't do application's JOIN command to do further communicate
         * so, application need do JOIN on reconnect
         * fireup an _reconnect callback here
         */
        if (!tcp_server_reconnect(srv)) {
            mtc_dbg("reconnect failure");
            
            reconnectok = false;
#ifndef EVENTLOOP
            return 0;
#endif
        }

#ifdef EVENTLOOP
        unsigned char lbuf[SBSIZE];
        memcpy(lbuf, buf, bsize);
        
        struct msqueue_entry *e = msqueue_entry_create();
        if (!e) {
            mtc_err("no mem");
            return 0;
        }
        e->ename = strdup(srv->evt->ename);
        e->cmd = strdup("_reconnect");
        if (reconnectok) hdf_set_value(e->hdfrcv, "success", "1");
        else hdf_set_value(e->hdfrcv, "success", "0");

        mssync_lock(&arg->callbacksync);
        msqueue_put(arg->callbackqueue, e);
        mssync_unlock(&arg->callbacksync);
        mssync_signal(&arg->callbacksync);

        if (reconnectok) {
            /*
             * suspend trigger thread, wait for application JOIN
             */
            sleep(1);
            rv = ssend(srv->fd, lbuf, bsize, MSG_NOSIGNAL);
            if (rv != bsize) return 0;
            return 1;
        } else return 0;
#endif
    }

    rv = ssend(srv->fd, buf, bsize, MSG_NOSIGNAL);
    if (rv != bsize) {
        if (rv < 0 && errno == EPIPE) {
            mtc_dbg("%s %d closed", srv->evt->ename, srv->fd);
            close(srv->fd);
            srv->fd = -1;
            /*
            if (!tcp_server_reconnect(srv)) return 0;
            rv = ssend(srv->fd, buf, bsize, MSG_NOSIGNAL);
            if (rv == bsize) return 1;
            */
        }
        return 0;
    }
    return 1;
}
コード例 #27
0
ファイル: otjt.c プロジェクト: kingiol/cmoon
int tjt_get_data(HDF *hdf, HASH *dbh, session_t *ses)
{
    char *buf, tbl[LEN_TB];
    size_t datalen;
    file_t *fl;
    ULIST *ul = NULL;
    int count, offset, aid, fid, ret;

    mdb_conn *dbsys, *dbtjt;

    dbsys = (mdb_conn*)hash_lookup(dbh, "Sys");
    dbtjt = (mdb_conn*)hash_lookup(dbh, "Tjt");

    PRE_DBOP(hdf, dbsys);
    PRE_DBOP(hdf, dbtjt);

    aid = ses->file->aid;
    fid = ses->file->id;
    snprintf(tbl, sizeof(tbl), "tjt_%d", aid);

    /* TODO ses->file not null all time? */
    //if (ses->file != NULL)
    lutil_fill_layout_by_file(dbsys, ses->file, hdf);
    if (file_get_info_by_id(dbsys, aid, NULL, -1, &fl) == RET_RBTOP_OK) {
        hdf_set_value(hdf, PRE_OUTPUT".navtitle", fl->remark);
        file_del(fl);
    }
    file_get_nav_by_id(dbsys, aid, PRE_OUTPUT, hdf);

    ret = file_check_user_power(hdf, dbsys, ses, ses->file, LMT_APPEND);
    if (ret == RET_RBTOP_OK) {
        hdf_set_value(hdf, PRE_OUTPUT".appendable", "1");
    }

    lutil_fetch_countf(hdf, dbtjt, tbl, "fid=%d", fid);
    mmisc_get_offset(hdf, &count, &offset);

    buf = mmc_getf(&datalen, 0, PRE_MMC_TJT".%d.%d", fid, offset);
    if (buf == NULL || datalen < sizeof(tjt_t)) {
        LDB_QUERY_RAW(dbtjt, "tjt_%d", TJT_QUERY_COL, "fid=%d ORDER BY uptime "
                      " LIMIT %d OFFSET %d", NULL, aid, fid, count, offset);
        mdb_set_rows(hdf, dbtjt, TJT_QUERY_COL, PRE_OUTPUT".atoms");
        lutil_image_expand(hdf, PRE_OUTPUT".atoms", "img", IMG_PATH, IMG_S, "imgurl");
        lcs_hdf2list(hdf, PRE_OUTPUT".atoms", tjt_hdf2item, &ul);
        ret = list_pack(ul, TJT_LEN, tjt_pack_nalloc, &buf, &datalen);
        if (ret == RET_RBTOP_OK) {
            mmc_storef(MMC_OP_SET, buf, datalen, HALF_HOUR, 0, PRE_MMC_TJT".%d.%d",
                       fid, offset);
        }
    } else {
        list_unpack(buf, tjt_unpack, datalen, &ul);
        ret = lcs_list2hdf(ul, PRE_OUTPUT".atoms", tjt_item2hdf, hdf);
        if (ret != RET_RBTOP_OK) {
            mtc_err("assembly tjt from mmc error");
            return RET_RBTOP_MMCERR;
        }
    }
    uListDestroyFunc(&ul, tjt_del);
    free(buf);

    return ret;
}
コード例 #28
0
ファイル: ltpl.c プロジェクト: adderly/cmoon
NEOERR* ltpl_parse_file(HASH *dbh, HASH *evth,
                        void *lib, char *dir, char *name, HASH *outhash)
{
    char *tp = NULL, *tpl = NULL, *val = NULL;
    HDF *node = NULL, *dhdf = NULL, *child = NULL, *thdf = NULL;
    CSPARSE *cs = NULL;
    STRING str;
    char fname[_POSIX_PATH_MAX], tok[64], *outfile;
    NEOERR* (*data_handler)(HDF *hdf, HASH *dbh, HASH *evth);
    NEOERR *err;
    
    memset(fname, 0x0, sizeof(fname));
    snprintf(fname, sizeof(fname), "%s/%s", dir, name);
    err = hdf_init(&node);
    if (err != STATUS_OK) return nerr_pass(err);
 
    err = hdf_read_file(node, fname);
    if (err != STATUS_OK) return nerr_pass(err);

    child = hdf_obj_child(node);
    while (child != NULL) {
        mtc_dbg("parse node %s", hdf_obj_name(child));
        string_init(&str);

        val = mcs_obj_attr(child, "merge");
        if (val) {
            ULIST *list;
            string_array_split(&list, val, ",", 10);
            ITERATE_MLIST(list) {
                snprintf(fname, sizeof(fname), "%s/%s",
                         dir, neos_strip((char*)list->items[t_rsv_i]));
                err = hdf_init(&dhdf);
                JUMP_NOK(err, wnext);
                err = hdf_read_file(dhdf, fname);
                JUMP_NOK(err, wnext);
                err = hdf_copy(child, NULL, dhdf);
                JUMP_NOK(err, wnext);
            }
            uListDestroy(&list, ULIST_FREE);
        }

        /*
         * can't use dataset directly, because we'll destroy the whole node
         */
        err = hdf_init(&dhdf);
        JUMP_NOK(err, wnext);
        err = hdf_get_node(child, PRE_CFG_DATASET, &thdf);
        JUMP_NOK(err, wnext);
        err = hdf_copy(dhdf, NULL, thdf);
        JUMP_NOK(err, wnext);
        
        err = cs_init(&cs, dhdf);
        JUMP_NOK(err, wnext);

        hdf_set_value(cs->hdf, "hdf.loadpaths.tpl", PATH_TPL);
        hdf_set_value(cs->hdf, "hdf.loadpaths.local", dir);

        err = cgi_register_strfuncs(cs);
        JUMP_NOK(err, wnext);
        err = mcs_register_bitop_functions(cs);
        JUMP_NOK(err, wnext);
        err = mcs_register_mkd_functions(cs);
        JUMP_NOK(err, wnext);
        err = mcs_register_string_uslice(cs);
        JUMP_NOK(err, wnext);

        tpl = hdf_get_value(child, PRE_CFG_LAYOUT, "null.html");
        snprintf(fname, sizeof(fname), "%s/%s", PATH_TPL, tpl);
        err = cs_parse_file(cs, fname);
        JUMP_NOK(err, wnext);

        if (outhash != NULL) {
            /*
             * store template for rend stage use
             */
            hdf_set_value(cs->hdf, PRE_RESERVE"."PRE_CFG_LAYOUT, tpl);
            
            /*
             * strdup the key, baby, because we'll free the hdf later
             */
            err = hash_insert(outhash, (void*)strdup(hdf_obj_name(child)), (void*)cs);
            JUMP_NOK(err, wnext);

            snprintf(tok, sizeof(tok), "%s_hdf", hdf_obj_name(child));
            err = hash_insert(outhash, (void*)strdup(tok), (void*)cs->hdf);
            JUMP_NOK(err, wnext);
        }

        if ((outfile = hdf_get_value(child, PRE_CFG_OUTPUT, NULL)) != NULL) {
            ltpl_prepare_rend(cs->hdf, tpl);
                
            /*
             * get_data
             */
            val = hdf_get_value(child, PRE_CFG_DATAER, NULL);
            if (val != NULL && lib) {
                data_handler = dlsym(lib, val);
                if( (tp = dlerror()) != NULL) {
                    mtc_err("%s", tp);
                    //continue;
                } else {
                    err = (*data_handler)(cs->hdf, dbh, evth);
                    TRACE_NOK(err);
                }
            }

            err = cs_render(cs, &str, mcs_strcb);
            JUMP_NOK(err, wnext);

            /*
             * produce output filename
             */
            val = mcs_hdf_attr(child, PRE_CFG_OUTPUT, "ftime");
            if (val) {
                char tm[LEN_TM];
                mutil_getdatetime(tm, sizeof(tm), val, 0);
                outfile = mstr_repstr(1, outfile, "$ftime$", tm);
            }
            snprintf(fname, sizeof(fname), PATH_DOC"%s", outfile);

            /*
             * output file
             */
            err = mfile_makesure_dir(fname);
            JUMP_NOK(err, wnext);

            err = mcs_str2file(str, fname);
            JUMP_NOK(err, wnext);
#ifdef DEBUG_HDF
            snprintf(fname, sizeof(fname), "%s/hdf.%s",
                     TC_ROOT, hdf_obj_name(child));
            hdf_write_file(child, fname);
#endif
        }

    wnext:
        if (cs != NULL && outhash == NULL)
            cs_destroy(&cs);
        string_clear(&str);
        child = hdf_obj_next(child);
    }
        
    if (node != NULL) hdf_destroy(&node);

    return STATUS_OK;
}
コード例 #29
0
ファイル: login.c プロジェクト: bigmaliang/sam
int main(int argc, char **argv, char **envp)
{
	CGI *cgi = NULL;
	NEOERR *err;
	mdb_conn *conn = NULL;

	/* skey, user, pass, return jsoncallback*/
	char *s, *u, *p, *r, *jcbk;
	/* keeptime(hours)  */
	int t;
	char tm[LEN_TM_GMT];
	
	//sleep(20);
	mtc_init("login");
	mconfig_parse_file(SITE_CONFIG, &g_cfg);
	mutil_wrap_fcgi(argc, argv, envp);
	if (mdb_init(&conn, DB_DSN) != MDB_ERR_NONE) {
		mtc_err("init db error %s", mdb_get_errmsg(conn));
		printf("Content-Type: text/html; charset=UTF-8\r\n\r\n");
		printf("{errcode: %d}", SAM_ERR_INIT);
		return 1;
	}
	
#ifndef DROP_FCGI
	while (FCGI_Accept() >= 0) {
#endif

		/*
		 * cgi init 
		 */
		err = cgi_init(&cgi, NULL);
		if (err != STATUS_OK) {
			mtc_err("init cgi error");
			printf("Content-Type: text/html; charset=UTF-8\r\n\r\n");
			printf("{errcode: %d}", SAM_ERR_INIT);
			goto opfinish;
		}
		err = cgi_parse(cgi);
		if (err != STATUS_OK) {
			mtc_err("parse cgi error");
			hdf_set_int_value(cgi->hdf, PRE_OUTPUT".errcode", SAM_ERR_PARSE);
			goto opfinish;
		}
#if 0
		if (mutil_client_attack_cookie(cgi->hdf, "login", 30, 60)) {
			mtc_err("client attack");
			hdf_set_int_value(cgi->hdf, PRE_OUTPUT".errcode", SAM_ERR_NEEDREST);
			goto opfinish;
		}
#endif

		u = hdf_get_value(cgi->hdf, PRE_COOKIE".samuser", NULL);
		s = hdf_get_value(cgi->hdf, PRE_COOKIE".samkey", NULL);
		if (s && u) {
			if (user_has_login(conn, u, s)) {
				hdf_set_copy(cgi->hdf, PRE_OUTPUT".samuser", PRE_COOKIE".samuser");
				hdf_set_copy(cgi->hdf, PRE_OUTPUT".samkey", PRE_COOKIE".samkey");
				goto done;
			}
		}
		
		u = hdf_get_value(cgi->hdf, PRE_QUERY".u", NULL);
		p = hdf_get_value(cgi->hdf, PRE_QUERY".p", NULL);
		if (!u || !p) {
			mtc_err("parameter miss %s %s", u, p);
			hdf_set_int_value(cgi->hdf, PRE_OUTPUT".errcode", SAM_ERR_NEEDINPUT);
			goto opfinish;
		}
		s = user_login_auth(conn, u, p);
		if (!s) {
			mtc_err("login error %s %s", u, p);
			hdf_set_int_value(cgi->hdf, PRE_OUTPUT".errcode", SAM_ERR_PASSW);
			goto opfinish;
		}

		cgiwrap_write(P3P_HEADER, strlen(P3P_HEADER));
		cgi_cookie_set(cgi, "samuser", u, NULL, SITE_DOMAIN, NULL, 1, 0);
		cgi_cookie_set(cgi, "samkey", s, NULL, SITE_DOMAIN, NULL, 1, 0);
#if 0
		t = hdf_get_int_value(cgi->hdf, PRE_QUERY".t", 0);
		mmisc_getdatetime_gmt(tm, sizeof(tm), "%A, %d-%b-%Y %T GMT", 60*60*t);
		cgi_cookie_set(cgi, "samkey", s, NULL, SITE_DOMAIN, tm, 1, 0);
#endif
		
		hdf_set_value(cgi->hdf, PRE_OUTPUT".samuser", u);
		hdf_set_value(cgi->hdf, PRE_OUTPUT".samkey", s);
		free(s);

	done:
		/*
		 * TODO set samkey, samuser to app's domain
		 * DONE this is done by jsonp
		 */
		hdf_set_value(cgi->hdf, PRE_OUTPUT".success", "1");
	opfinish:
		if (cgi) {
			r = hdf_get_value(cgi->hdf, PRE_QUERY".r", NULL);
			if (r) {
				cgi_redirect(cgi, r);
			} else {
				jcbk = hdf_get_value(cgi->hdf, PRE_QUERY".jsoncallback", NULL);
				if (jcbk != NULL) {
					mjson_execute_hdf(cgi->hdf, jcbk, 0);
				} else {
					mjson_output_hdf(cgi->hdf, 0);
				}
			}
#ifdef DEBUG_HDF
			hdf_write_file(cgi->hdf, HF_LOG_PATH"hdf.login");
#endif
			cgi_destroy(&cgi);
		}
		
#ifndef DROP_FCGI
 	} /* FCGI_Accept() */
#endif

	mdb_destroy(conn);
	return 0;
}
コード例 #30
0
ファイル: viki.c プロジェクト: kingiol/cmoon
int main(int argc, char **argv, char **envp)
{
    CGI *cgi;
    NEOERR *err;
    int ret;

    HASH *dbh;
    HASH *tplh;
    session_t *session = NULL;
    char *requri, *jsoncb;

    int (*data_handler)(CGI *cgi, HASH *dbh, session_t *session);
    void *lib;

    //sleep(20);
    mconfig_parse_file(SITE_CONFIG, &g_cfg);
    mtc_init(TC_ROOT"viki");

    ret = ltpl_init(&tplh);
    if (ret != RET_RBTOP_OK) {
        mtc_err("init templates error");
        mutil_redirect("初始化模板失败", TGT_SELF, URL_CLOSE, true);
        return ret;
    }

    ret = ldb_init(&dbh);
    if (ret != RET_RBTOP_OK) {
        mtc_err("init db error");
        mutil_redirect("初始化数据库失败", TGT_SELF, URL_CLOSE, true);
        return ret;
    }

    lib = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
    if (lib == NULL) {
        mtc_err("possible? %s", dlerror());
        mutil_redirect("初始化库函数失败", TGT_SELF, URL_CLOSE, true);
        return 1;
    }
    
#ifndef DROP_FCGI
    cgiwrap_init_emu(NULL, &read_cb, &printf_cb, &write_cb, NULL, NULL, NULL);
    while (FCGI_Accept() >= 0) {
#endif
        cgiwrap_init_std(argc, argv, environ);
        err = cgi_init(&cgi, NULL);
        JUMP_NOK_CGI(err, response);
        err = cgi_parse(cgi);
        JUMP_NOK_CGI(err, response);

#ifdef NCGI_MODE
        hdf_set_value(cgi->hdf, PRE_REQ_URI_RW, "/csc/hc");
        hdf_set_value(cgi->hdf, PRE_COOKIE".uin", "1001");
        hdf_set_value(cgi->hdf, PRE_COOKIE".uname", "bigml");
        hdf_set_value(cgi->hdf, PRE_COOKIE".musn", "8Y]u0|v=*MS]U3J");
#endif
        
        ret = session_init(cgi->hdf, dbh, &session);
        if (ret != RET_RBTOP_OK) {
            mtc_err("init session failure");
            goto response;
        }

        requri = hdf_get_value(cgi->hdf, PRE_REQ_URI_RW, "NULL");
        if (mutil_client_attack(cgi->hdf, requri, LMT_CLI_ATTACK,
                                PERIOD_CLI_ATTACK)) {
            goto response;
        }
        
        ret = lfile_access_rewrited(cgi, dbh, session);
        if (ret != RET_RBTOP_OK) {
            goto response;
        }

        data_handler = lutil_get_data_handler(lib, cgi);
        if (data_handler == NULL) {
            mtc_err("get handler failure");
            ret = RET_RBTOP_NEXIST;
            goto response;
        }

        ret = (*data_handler)(cgi, dbh, session);
        
    response:
        if (cgi != NULL && cgi->hdf != NULL) {
#ifdef DEBUG_HDF
            hdf_write_file(cgi->hdf, TC_ROOT"hdf.viki");
#endif
            switch (CGI_REQ_TYPE(cgi)) {
            case CGI_REQ_HTML:
                if (CGI_REQ_METHOD(cgi) != CGI_REQ_GET) {
                    goto resp_ajax;
                }
                if (ret != RET_RBTOP_OK && ret == RET_RBTOP_NEXIST) {
                    cgi_redirect(cgi, "/404.html");
                } else {
                    ret = ltpl_render(cgi, tplh, session);
                    if (ret != RET_RBTOP_OK) {
                        if (ret == RET_RBTOP_NEXIST)
                            cgi_redirect(cgi, "/404.html");
                        else
                            cgi_redirect(cgi, "/503.html");
                    }
                }
                break;
            case CGI_REQ_AJAX:
            resp_ajax:
                ldb_opfinish_json(ret, cgi->hdf, NULL, 0);
                jsoncb = hdf_get_value(cgi->hdf, PRE_REQ_AJAX_FN, NULL);
                if (jsoncb != NULL) {
                    mjson_execute_hdf(cgi->hdf, jsoncb, session->tm_cache_browser);
                } else {
                    mjson_output_hdf(cgi->hdf, session->tm_cache_browser);
                }
                break;
            default:
                cgi_redirect(cgi, "/503.html");
                break;
            }
            cgi_destroy(&cgi);
            session_destroy(&session);
        }
#ifndef DROP_FCGI
    }
#endif

    ldb_destroy(dbh);
    ltpl_destroy(tplh);
    mconfig_cleanup(&g_cfg);
    return 0;
}