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 void* mevent_start_base_entry(void *arg) { int rv; struct timespec ts; struct queue_entry *q; struct event_entry *e = (struct event_entry*)arg; int *mypos = _tls_get_mypos(); *mypos = e->cur_thread; mtc_dbg("I'm %s %dnd thread", e->name, *mypos); for (;;) { /* Condition waits are specified with absolute timeouts, see * pthread_cond_timedwait()'s SUSv3 specification for more * information. We need to calculate it each time. * We sleep for 1 sec. There's no real need for it to be too * fast (it's only used so that stop detection doesn't take * long), but we don't want it to be too slow either. */ mutil_utc_time(&ts); ts.tv_sec += 1; rv = 0; queue_lock(e->op_queue[*mypos]); while (queue_isempty(e->op_queue[*mypos]) && rv == 0) { rv = queue_timedwait(e->op_queue[*mypos], &ts); } if (rv != 0 && rv != ETIMEDOUT) { errlog("Error in queue_timedwait()"); /* When the timedwait fails the lock is released, so * we need to properly annotate this case. */ __release(e->op_queue[*mypos]->lock); continue; } q = queue_get(e->op_queue[*mypos]); queue_unlock(e->op_queue[*mypos]); if (q == NULL) { if (e->loop_should_stop) { break; } else { continue; } } mtc_dbg("%s %d process", e->name, *mypos); e->process_driver(e, q, *mypos); /* Free the entry that was allocated when tipc queued the * operation. This also frees it's components. */ queue_entry_free(q); } return NULL; }
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; }
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* 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; }
NEOERR* ltpl_parse_dir(char *dir, HASH *outhash) { struct dirent **eps = NULL; int n; NEOERR *err; if (!dir) return nerr_raise(NERR_ASSERT, "can't read null directory"); HASH *dbh, *evth; void *lib = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL); if (!lib) return nerr_raise(NERR_SYSTEM, "dlopen %s", dlerror()); err = ldb_init(&dbh); if (err != STATUS_OK) return nerr_pass(err); err = levt_init(&evth); if (err != STATUS_OK) return nerr_pass(err); n = scandir(dir, &eps, ltpl_config, alphasort); for (int i = 0; i < n; i++) { mtc_dbg("parse file %s", eps[i]->d_name); err = ltpl_parse_file(dbh, evth, lib, dir, eps[i]->d_name, outhash); TRACE_NOK(err); free(eps[i]); } ldb_destroy(dbh); levt_destroy(evth); dlclose(lib); if (n > 0) free(eps); else mtc_warn("no .hdf file found in %s", dir); return STATUS_OK; }
static void city_process_driver(EventEntry *entry, QueueEntry *q) { struct city_entry *e = (struct city_entry*)entry; NEOERR *err; int ret; struct city_stats *st = &(e->st); st->msg_total++; mtc_dbg("process cmd %u", q->operation); switch (q->operation) { CASE_SYS_CMD(q->operation, q, e->cd, err); case REQ_CMD_CITY_BY_IP: err = city_cmd_ip(e, q); break; case REQ_CMD_CITY_BY_ID: err = city_cmd_id(e, q); break; case REQ_CMD_CITY_BY_S: err = city_cmd_s(e, q); break; case REQ_CMD_PLACE_GET: err = place_cmd_get(e, q); break; case REQ_CMD_STATS: st->msg_stats++; err = STATUS_OK; hdf_set_int_value(q->hdfsnd, "msg_total", st->msg_total); hdf_set_int_value(q->hdfsnd, "msg_unrec", st->msg_unrec); hdf_set_int_value(q->hdfsnd, "msg_badparam", st->msg_badparam); hdf_set_int_value(q->hdfsnd, "msg_stats", st->msg_stats); hdf_set_int_value(q->hdfsnd, "proc_suc", st->proc_suc); hdf_set_int_value(q->hdfsnd, "proc_fai", st->proc_fai); break; default: st->msg_unrec++; err = nerr_raise(REP_ERR_UNKREQ, "unknown command %u", q->operation); break; } NEOERR *neede = mcs_err_valid(err); ret = neede ? neede->error : REP_OK; if (PROCESS_OK(ret)) { st->proc_suc++; } else { st->proc_fai++; if (ret == REP_ERR_BADPARAM) { st->msg_badparam++; } TRACE_ERR(q, ret, err); } if (q->req->flags & FLAGS_SYNC) { reply_trigger(q, ret); } }
void eloop_stop(moc_arg *arg) { if (!m_thread) return; mtc_dbg("end event loop thread..."); m_stop = true; pthread_join(*m_thread, NULL); free(m_thread); m_thread = NULL; }
static void dyn_process_driver(struct event_entry *entry, struct queue_entry *q) { struct dyn_entry *e = (struct dyn_entry*)entry; NEOERR *err; int ret; mdb_conn *db = e->db; struct cache *cd = e->cd; struct dyn_stats *st = &(e->st); st->msg_total++; mtc_dbg("process cmd %u", q->operation); switch (q->operation) { CASE_SYS_CMD(q->operation, q, e->cd, err); case REQ_CMD_ADDTRACK: err = dyn_cmd_addtrack(q, cd, db); break; case REQ_CMD_GETADMIN: err = dyn_cmd_getadmin(q, cd, db); break; case REQ_CMD_STATS: st->msg_stats++; err = STATUS_OK; hdf_set_int_value(q->hdfsnd, "msg_total", st->msg_total); hdf_set_int_value(q->hdfsnd, "msg_unrec", st->msg_unrec); hdf_set_int_value(q->hdfsnd, "msg_badparam", st->msg_badparam); hdf_set_int_value(q->hdfsnd, "msg_stats", st->msg_stats); hdf_set_int_value(q->hdfsnd, "proc_suc", st->proc_suc); hdf_set_int_value(q->hdfsnd, "proc_fai", st->proc_fai); break; default: st->msg_unrec++; err = nerr_raise(REP_ERR_UNKREQ, "unknown command %u", q->operation); break; } NEOERR *neede = mcs_err_valid(err); ret = neede ? neede->error : REP_OK; if (PROCESS_OK(ret)) { st->proc_suc++; } else { st->proc_fai++; if (ret == REP_ERR_BADPARAM) { st->msg_badparam++; } TRACE_ERR(q, ret, err); } if (q->req->flags & FLAGS_SYNC) { reply_trigger(q, ret); } }
void mssrv_close(moc_t *evt, int order, int fd) { if (!evt) return; mtc_dbg("%s %d %d closed", evt->ename, order, fd); if (evt->nservers < order) return; moc_srv *srv = &(evt->servers[order]); if (srv->fd != fd) return; close(srv->fd); srv->fd = -1; }
NEOERR* ldml_parse_file(char *dir, char *name, HASH *outhash) { char fname[_POSIX_PATH_MAX], *attrval = NULL; HDF *node, *child, *dhdf; STRING str; 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); attrval = mcs_obj_attr(child, "merge"); if (attrval) { ULIST *list; string_array_split(&list, attrval, ",", 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); } wnext: string_clear(&str); child = hdf_obj_next(child); } err = hash_insert(outhash, (void*)strdup(name), (void*)node); JUMP_NOK(err, wnext); return STATUS_OK; }
struct base_user *base_user_new(struct base_info *binfo, char *uid, QueueEntry *q, struct base_user *ruser, void (*user_destroy)(void *arg)) { if (!binfo || !uid || !q || !q->req) return NULL; struct base_user *user; user = base_user_find(binfo, uid); if (user) return user; if (ruser) user = ruser; else user = calloc(1, sizeof(struct base_user)); if (!user) return NULL; struct sockaddr_in *clisa = (struct sockaddr_in*)q->req->clisa; //strncpy(user->ip, inet_ntoa(clisa), 16); user->uid = strdup(uid); user->fd = q->req->fd; inet_ntop(clisa->sin_family, &clisa->sin_addr, user->ip, sizeof(user->ip)); user->port = ntohs(clisa->sin_port); user->tcpsock = q->req->tcpsock; user->baseinfo = binfo; /* * used on user close */ if (q->req->tcpsock) { q->req->tcpsock->appdata = user; if (user_destroy) q->req->tcpsock->on_close = user_destroy; else q->req->tcpsock->on_close = base_user_destroy; } /* * binfo */ hash_insert(binfo->userh, (void*)strdup(uid), (void*)user); binfo->usernum++; mtc_dbg("%s %s %d join", uid, user->ip, user->port); return user; }
void base_user_destroy(void *arg) { struct base_user *user = (struct base_user*)arg; struct base_info *binfo = user->baseinfo; if (!user || !binfo) return; mtc_dbg("%s %s %d destroy", user->uid, user->ip, user->port); hash_remove(binfo->userh, user->uid); if (binfo->usernum > 0) binfo->usernum--; SAFE_FREE(user->uid); SAFE_FREE(user); return; }
NEOERR* masset_node_load(char *dir, char *name, RendAsset **pa) { AssetDriver *driver; RendAsset *asset = NULL; int driverindex; HASH *mh; NEOERR *err; mh = hash_lookup(g_datah, ASSET_KEY); MCS_NOT_NULLC(name, pa, mh); *pa = NULL; asset = hash_lookup(mh, name); if (asset) goto done; char *p = strrchr(name, '.'); if (p) p = p + 1; if (!p || !*p) return nerr_raise(NERR_ASSERT, "unknown asset type %s", name); driverindex = uListIndex(asset_drivers, p, asset_driver_comp); if (driverindex < 0) return nerr_raise(NERR_ASSERT, "unknown asset type %s", name); err = uListGet(asset_drivers, driverindex, (void**)&driver); if (err != STATUS_OK) return nerr_pass(err); mtc_dbg("load asset %s%s", dir, name); err = driver->load(dir, name, &asset); if (err != STATUS_OK) return nerr_pass(err); if (!asset) return nerr_raise(NERR_ASSERT, "asset node %s empty", name); asset->name = strdup(name); asset->driverindex = driverindex; hash_remove(mh, name); hash_insert(mh, strdup(name), asset); done: *pa = asset; return STATUS_OK; }
bool base_user_quit(struct base_info *binfo, char *uid, QueueEntry *q, void (*user_destroy)(void *arg)) { struct base_user *user; user = base_user_find(binfo, uid); if (!user) return false; if (q && q->req->tcpsock) { if (q->req->tcpsock == user->tcpsock && q->req->fd == user->fd) return false; } mtc_dbg("%s %s %d quit", user->uid, user->ip, user->port); tcp_socket_remove_ref(user->tcpsock); /* user may be destroied by remove_ref(), so, don't write */ //user->tcpsock = NULL; return true; }
void masset_node_unload(void *p) { NEOERR *err; if (!p) return; RendAsset *a = p; AssetDriver *driver; err = uListGet(asset_drivers, a->driverindex, (void**)&driver); RETURN_NOK(err); mtc_dbg("unload asset %s", a->name); if (driver) driver->unload(a); SAFE_FREE(a->name); SAFE_FREE(a); /* TODO remove from asset hash table? */ }
NEOERR* ldml_parse_dir(char *dir, HASH *outhash) { struct dirent **eps = NULL; int n; NEOERR *err; if (!dir) return nerr_raise(NERR_ASSERT, "can't read null directory"); n = scandir(dir, &eps, ldml_config, alphasort); for (int i = 0; i < n; i++) { mtc_dbg("parse file %s", eps[i]->d_name); err = ldml_parse_file(dir, eps[i]->d_name, outhash); TRACE_NOK(err); free(eps[i]); } if (n > 0) free(eps); else mtc_warn("no .hdf file found in %s", dir); return STATUS_OK; }
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; }
/* * application logic message, called by msparse_buf() */ static NEOERR* msparse_msg(moc_srv *srv, unsigned char *buf, size_t len, moc_arg *arg) { uint32_t id, reply; unsigned char *payload; size_t psize, rv; MOC_NOT_NULLB(arg, arg->evth); if (!srv || !buf || len < 8) return nerr_raise(NERR_ASSERT, "illegal packet"); //MSG_DUMP("recv: ", buf, len); /* The header is: * 4 bytes ID * 4 bytes Reply Code * Variable Payload */ id = ntohl(* ((uint32_t *) buf)); reply = ntohl(* ((uint32_t *) buf + 1)); payload = buf + 8; psize = len - 8; if (id == 0 && reply == 10000) { /* * server push */ if (psize < 4) return nerr_raise(NERR_ASSERT, "server pushed empty message"); struct msqueue_entry *e = msqueue_entry_create(); if (!e) return nerr_raise(NERR_NOMEM, "alloc msqueue entry"); rv = unpack_hdf(payload + 4, psize - 4, &(e->hdfrcv)); if (rv <= 0) return nerr_raise(NERR_ASSERT, "server pushed illegal message"); //TRACE_HDF(e->hdfrcv); char *cmd = NULL; HDF_ATTR *attr = hdf_get_attr(e->hdfrcv, "_Reserve"); while (attr != NULL) { if (!strcmp(attr->key, "cmd")) cmd = attr->value; attr = attr->next; } if (!cmd) return nerr_raise(NERR_ASSERT, "cmd not supplied"); e->ename = strdup(srv->evt->ename); e->cmd = strdup(cmd); mtc_dbg("receive cmd %s", cmd); hdf_remove_tree(e->hdfrcv, "_Reserve"); mssync_lock(&arg->callbacksync); msqueue_put(arg->callbackqueue, e); mssync_unlock(&arg->callbacksync); /* * notify callback thread */ mssync_signal(&arg->callbacksync); } else { /* * server response */ if (id < g_reqid) return nerr_raise(NERR_ASSERT, "id not match %d %d", g_reqid, id); if (psize >= 4) { mssync_lock(&(arg->mainsync)); rv = unpack_hdf(payload + 4, psize - 4, &(srv->evt->hdfrcv)); mssync_unlock(&(arg->mainsync)); if (rv <= 0) return nerr_raise(NERR_ASSERT, "server responsed illegal message"); //TRACE_HDF(srv->evt->hdfrcv); } /* * notify main thread */ mssync_signal(&(arg->mainsync)); } return STATUS_OK; }
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; }
static void* el_routine(void *arg) { moc_arg *earg = (moc_arg*)arg; HASH *evth = (HASH*)earg->evth; char *key = NULL; struct el_con conn[MOC_MAX_CON]; int num_conn = 0; mtc_dbg("start event loop thread..."); fd_set readset; struct timeval tv; for (;;) { memset(conn, 0x0, sizeof(conn)); num_conn = 0; key = NULL; /* * we need refresh conn[] array after server_reconnect() * we can do this by signal, but it's complex * and the num_conn normaly <= 1000 * so, refresh conn[] per select(or per 10 select :D). */ moc_t *evt = hash_next(evth, (void**)&key); while (evt) { for (int i = 0; i < evt->nservers && num_conn < MOC_MAX_CON; i++) { moc_srv *srv = &(evt->servers[i]); if (srv->fd > 0) { conn[num_conn].name = strdup(evt->ename); conn[num_conn].order = i; conn[num_conn].fd = srv->fd; num_conn++; } } evt = hash_next(evth, (void**)&key); } int maxfd = -1; FD_ZERO(&readset); for (int i = 0; i < num_conn; i++) { if (conn[i].fd > 0) { if (conn[i].fd > maxfd) maxfd = conn[i].fd; FD_SET(conn[i].fd, &readset); } } tv.tv_sec = 0; tv.tv_usec = 100000; select(maxfd + 1, &readset, NULL, NULL, &tv); for (int i = 0; i < num_conn; i++) { if (FD_ISSET(conn[i].fd, &readset)) { int rv = recv(conn[i].fd, static_buf, SBSIZE, 0); mtc_dbg("msg from %s %d fd %d len %d %d %s", conn[i].name, conn[i].order, conn[i].fd, rv, errno, strerror(errno)); if (rv < 0 && errno == EAGAIN) { /* * We were awoken but have no data to read, so we do nothing */ goto next; } else if (rv == -1 && errno == ETIMEDOUT) { /* * network unreachable * may be reachable later, notify user */ struct msqueue_entry *e = msqueue_entry_create(); if (e) { e->ename = strdup(conn[i].name); e->cmd = strdup("_connectlost"); mssync_lock(&earg->callbacksync); msqueue_put(earg->callbackqueue, e); mssync_unlock(&earg->callbacksync); mssync_signal(&earg->callbacksync); } goto next; } else if (rv <= 0) { /* * Orderly shutdown or error; * close the file descriptor in either case. */ evt = hash_lookup(evth, conn[i].name); if (evt) mssrv_close(evt, conn[i].order, conn[i].fd); conn[i].fd = -1; goto next; } evt = hash_lookup(evth, conn[i].name); if (!evt) mtc_err("%s not in evth", conn[i].name); else { moc_srv *srv = &(evt->servers[conn[i].order]); if (!srv) { mtc_err("%s out of order %d %d", conn[i].name, conn[i].order, evt->nservers); goto next; } if (srv->buf == NULL) msparse_buf(evt, conn[i].order, conn[i].fd, static_buf, rv, earg); else { memcpy(srv->buf + srv->len, static_buf, rv); srv->len += rv; msparse_buf(evt, conn[i].order, conn[i].fd, srv->buf, srv->len, earg); } } } next: if (conn[i].name) free(conn[i].name); } if (m_stop) break; } return NULL; }
static void aic_process_driver(struct event_entry *entry, struct queue_entry *q) { struct aic_entry *e = (struct aic_entry*)entry; NEOERR *err; int ret; mdb_conn *db = e->db; struct cache *cd = e->cd; struct aic_stats *st = &(e->st); st->msg_total++; mtc_dbg("process cmd %u", q->operation); switch (q->operation) { CASE_SYS_CMD(q->operation, q, e->cd, err); case REQ_CMD_APPINFO: err = aic_cmd_appinfo(q, cd, db); break; case REQ_CMD_APPNEW: err = aic_cmd_appnew(q, cd, db); break; case REQ_CMD_APPUP: err = aic_cmd_appup(q, cd, db); break; case REQ_CMD_APPDEL: err = aic_cmd_appdel(q, cd, db); break; case REQ_CMD_APP_GETSECY: err = aic_cmd_app_getsecy(q, cd, db); break; case REQ_CMD_APP_SETSECY: err = aic_cmd_app_setsecy(q, cd, db); break; case REQ_CMD_APPUSERS: err = aic_cmd_appusers(q, cd, db); break; case REQ_CMD_APPUSERIN: err = aic_cmd_appuserin(q, cd, db); break; case REQ_CMD_APPUSEROUT: err = aic_cmd_appuserout(q, cd, db); break; case REQ_CMD_APPUSERUP: err = aic_cmd_appuserup(q, cd, db); break; case REQ_CMD_APP_O_USERS: err = aic_cmd_appousers(q, cd, db); break; case REQ_CMD_APP_GETRLINK: err = aic_cmd_app_getrlink(q, cd, db); break; case REQ_CMD_APP_SETRLINK: err = aic_cmd_app_setrlink(q, cd, db); break; case REQ_CMD_STATS: st->msg_stats++; err = STATUS_OK; hdf_set_int_value(q->hdfsnd, "msg_total", st->msg_total); hdf_set_int_value(q->hdfsnd, "msg_unrec", st->msg_unrec); hdf_set_int_value(q->hdfsnd, "msg_badparam", st->msg_badparam); hdf_set_int_value(q->hdfsnd, "msg_stats", st->msg_stats); hdf_set_int_value(q->hdfsnd, "proc_suc", st->proc_suc); hdf_set_int_value(q->hdfsnd, "proc_fai", st->proc_fai); break; default: st->msg_unrec++; err = nerr_raise(REP_ERR_UNKREQ, "unknown command %u", q->operation); break; } NEOERR *neede = mcs_err_valid(err); ret = neede ? neede->error : REP_OK; if (PROCESS_OK(ret)) { st->proc_suc++; } else { st->proc_fai++; if (ret == REP_ERR_BADPARAM) { st->msg_badparam++; } TRACE_ERR(q, ret, err); } if (q->req->flags & FLAGS_SYNC) { reply_trigger(q, ret); } }
static void aux_process_driver(EventEntry *entry, QueueEntry *q) { struct aux_entry *e = (struct aux_entry*)entry; NEOERR *err; int ret; struct aux_stats *st = &(e->st); st->msg_total++; mtc_dbg("process cmd %u", q->operation); switch (q->operation) { CASE_SYS_CMD(q->operation, q, e->cd, err); case REQ_CMD_CMT_GET: err = aux_cmd_cmtget(e, q); break; case REQ_CMD_CMT_ADD: err = aux_cmd_cmtadd(e, q); break; case REQ_CMD_CMT_DEL: err = aux_cmd_cmtdel(e, q); break; case REQ_CMD_MEMORY_GET: err = aux_cmd_memoryget(e, q); break; case REQ_CMD_MEMORY_ADD: err = aux_cmd_memoryadd(e, q); break; case REQ_CMD_MEMORY_MOD: err = aux_cmd_memorymod(e, q); break; case REQ_CMD_AUX_EMAIL_ADD: err = aux_cmd_emailadd(e, q); break; case REQ_CMD_AUX_INBOX_ADD: err = aux_cmd_inboxadd(e, q); break; case REQ_CMD_STATS: st->msg_stats++; err = STATUS_OK; hdf_set_int_value(q->hdfsnd, "msg_total", st->msg_total); hdf_set_int_value(q->hdfsnd, "msg_unrec", st->msg_unrec); hdf_set_int_value(q->hdfsnd, "msg_badparam", st->msg_badparam); hdf_set_int_value(q->hdfsnd, "msg_stats", st->msg_stats); hdf_set_int_value(q->hdfsnd, "proc_suc", st->proc_suc); hdf_set_int_value(q->hdfsnd, "proc_fai", st->proc_fai); break; default: st->msg_unrec++; err = nerr_raise(REP_ERR_UNKREQ, "unknown command %u", q->operation); break; } NEOERR *neede = mcs_err_valid(err); ret = neede ? neede->error : REP_OK; if (PROCESS_OK(ret)) { st->proc_suc++; } else { st->proc_fai++; if (ret == REP_ERR_BADPARAM) { st->msg_badparam++; } TRACE_ERR(q, ret, err); } if (q->req->flags & FLAGS_SYNC) { reply_trigger(q, ret); } }
NEOERR* ltpl_parse_file(HASH *dbh, void *lib, char *dir, char *name, HASH *outhash) { char *tp = NULL, *tpl = NULL, *val = NULL; HDF *node = NULL, *dhdf = NULL, *child = NULL; CSPARSE *cs = NULL; STRING str; char fname[_POSIX_PATH_MAX], tok[64]; NEOERR* (*data_handler)(HDF *hdf, HASH *dbh); 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 = mutil_obj_attr(child, "merge"); if (val) { snprintf(fname, sizeof(fname), "%s/%s", dir, val); 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); } err = cs_init(&cs, hdf_get_obj(child, PRE_CFG_DATASET)); JUMP_NOK(err, wnext); 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); 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) { /* * 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); if (hdf_get_obj(child, PRE_CFG_DATASET)) { err = hdf_init(&dhdf); JUMP_NOK(err, wnext); err = hdf_copy(dhdf, NULL, hdf_get_obj(child, PRE_CFG_DATASET)); JUMP_NOK(err, wnext); snprintf(tok, sizeof(tok), "%s_hdf", hdf_obj_name(child)); err = hash_insert(outhash, (void*)strdup(tok), (void*)dhdf); JUMP_NOK(err, wnext); } } if (hdf_get_value(child, PRE_CFG_OUTPUT, NULL) != NULL) { ltpl_prepare_rend(hdf_get_obj(child, PRE_CFG_DATASET), 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)(hdf_get_obj(child, PRE_CFG_DATASET), dbh); TRACE_NOK(err); } } err = cs_render(cs, &str, mcs_strcb); JUMP_NOK(err, wnext); snprintf(fname, sizeof(fname), PATH_DOC"%s", hdf_get_value(child, PRE_CFG_OUTPUT, "null.html")); err = mutil_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; }