Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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);
    }
}
Exemple #8
0
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;
}
Exemple #9
0
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);
    }
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
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? */
}
Exemple #17
0
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;
}
Exemple #18
0
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;
}
Exemple #19
0
/*
 * 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;
}
Exemple #20
0
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;
}
Exemple #21
0
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;
}
Exemple #22
0
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);
    }
}
Exemple #23
0
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);
    }
}
Exemple #24
0
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;
}