⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_disco.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 2 页
字号:
}/** build a disco items result, active sessions */static void _disco_sessions_result(module_t mod, disco_t d, pkt_t pkt) {    int ns;    sess_t sess;    ns = nad_add_namespace(pkt->nad, uri_DISCO_ITEMS, NULL);    nad_append_elem(pkt->nad, ns, "query", 2);    nad_append_attr(pkt->nad, -1, "node", "sessions");    if(xhash_iter_first(mod->mm->sm->sessions))        do {            xhash_iter_get(mod->mm->sm->sessions, NULL, (void **) &sess);            nad_append_elem(pkt->nad, ns, "item", 3);            nad_append_attr(pkt->nad, -1, "jid", jid_full(sess->jid));            nad_append_attr(pkt->nad, -1, "name", "Active session");        } while(xhash_iter_next(mod->mm->sm->sessions));}/** catch responses and populate the table; respond to requests */static mod_ret_t _disco_pkt_sm(mod_instance_t mi, pkt_t pkt) {    module_t mod = mi->mod;    disco_t d = (disco_t) mod->private;    pkt_t result;    int node;        /* disco info results go to a seperate function */    if(pkt->type == pkt_IQ_RESULT && pkt->ns == ns_DISCO_INFO)        return _disco_pkt_sm_populate(mi, pkt);    /* we want disco, browse or agents gets */    if(pkt->type != pkt_IQ || !(pkt->ns == ns_DISCO_INFO || pkt->ns == ns_DISCO_ITEMS || pkt->ns == ns_BROWSE || pkt->ns == ns_AGENTS))        return mod_PASS;    /* generate the caches if we haven't yet */    if(d->disco_info_result == NULL)        _disco_generate_packets(mod, d);    /* they want to know about us */    if(pkt->ns == ns_DISCO_INFO) {        result = pkt_dup(d->disco_info_result, jid_full(pkt->from), jid_full(pkt->to));        pkt_id(pkt, result);        pkt_free(pkt);        /* off it goes */        pkt_router(result);        return mod_HANDLED;    }    /* handle agents */    if(pkt->ns == ns_AGENTS) {        /* make sure we're supporting compat */        if(!d->agents)            return -stanza_err_NOT_ALLOWED;        result = pkt_dup(d->agents_result, jid_full(pkt->from), jid_full(pkt->to));        pkt_id(pkt, result);        pkt_free(pkt);        /* off it goes */        pkt_router(result);        return mod_HANDLED;    }    /* handle browse */    if(pkt->ns == ns_BROWSE) {        /* make sure we're supporting compat */        if(!d->browse)            return -stanza_err_NOT_ALLOWED;        result = pkt_dup(d->browse_result, jid_full(pkt->from), jid_full(pkt->to));        pkt_id(pkt, result);        pkt_free(pkt);        /* off it goes */        pkt_router(result);        return mod_HANDLED;    }    /* they want to know who we know about */    node = nad_find_attr(pkt->nad, 2, -1, "node", NULL);    if(node < 0) {        /* no node, so toplevel services */        result = pkt_dup(d->disco_items_result, jid_full(pkt->from), jid_full(pkt->to));        pkt_id(pkt, result);        pkt_free(pkt);        /* if they have privs, them show them any administrative things they can disco to */        if(aci_check(mod->mm->sm->acls, "disco", result->to)) {            nad_append_elem(result->nad, NAD_ENS(result->nad, 2), "item", 3);            nad_append_attr(result->nad, -1, "jid", mod->mm->sm->id);            nad_append_attr(result->nad, -1, "node", "sessions");            nad_append_attr(result->nad, -1, "name", "Active sessions");        }        pkt_router(result);        return mod_HANDLED;    }    /* active sessions */    if(NAD_AVAL_L(pkt->nad, node) == 8 && strncmp("sessions", NAD_AVAL(pkt->nad, node), 8) == 0) {        /* priviliged op, make sure they're allowed */        if(!aci_check(mod->mm->sm->acls, "disco", pkt->from))            return -stanza_err_ITEM_NOT_FOUND;  /* we never advertised it, so we can pretend its not here */        result = pkt_create(mod->mm->sm, "iq", "result", jid_full(pkt->from), jid_full(pkt->to));        pkt_id(pkt, result);        pkt_free(pkt);        _disco_sessions_result(mod, d, result);        /* off it goes */        pkt_router(result);        return mod_HANDLED;    }    /* I dunno what they're asking for */    return -stanza_err_ITEM_NOT_FOUND;}/** legacy support for agents requests from sessions */static mod_ret_t _disco_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) {    module_t mod = mi->mod;    disco_t d = (disco_t) mod->private;    pkt_t result;    /* we want agents gets */    if(pkt->type != pkt_IQ || pkt->ns != ns_AGENTS || pkt->to != NULL)        return mod_PASS;    /* fail if its not enabled */    if(!d->agents)        return -stanza_err_NOT_ALLOWED;    /* generate the caches if we haven't yet */    if(d->disco_info_result == NULL)        _disco_generate_packets(mod, d);    /* pre-canned response */    result = pkt_dup(d->agents_result, NULL, NULL);    pkt_id(pkt, result);    pkt_free(pkt);    /* off it goes */    pkt_sess(result, sess);    return mod_HANDLED;}/** update the table for component changes */static mod_ret_t _disco_pkt_router(mod_instance_t mi, pkt_t pkt){    module_t mod = mi->mod;    disco_t d = (disco_t) mod->private;    service_t svc;    pkt_t request;    int ns;    /* we want advertisements with a from address */    if(pkt->from == NULL || !(pkt->rtype & route_ADV))        return mod_PASS;    /* component online */    if(pkt->rtype == route_ADV)    {        log_debug(ZONE, "presence from component %s, issuing discovery request", jid_full(pkt->from));        /* new disco get packet */        request = pkt_create(mod->mm->sm, "iq", "get", jid_full(pkt->from), mod->mm->sm->id);        ns = nad_add_namespace(request->nad, uri_DISCO_INFO, NULL);        nad_append_elem(request->nad, ns, "query", 2);        pkt_router(request);        /* done with this */        pkt_free(pkt);        return mod_HANDLED;    }    /* it went away. find it and remove it */    svc = xhash_get(d->dyn, jid_full(pkt->from));    if(svc != NULL)    {        log_debug(ZONE, "dropping entry for %s", jid_full(pkt->from));        xhash_zap(d->dyn, jid_full(pkt->from));        jid_free(svc->jid);        xhash_free(svc->features);        free(svc);        /* unify */        _disco_unify_lists(d);        _disco_generate_packets(mod, d);    }        /* done */    pkt_free(pkt);    return mod_HANDLED;}static void _disco_free_walker(xht h, const char *key, void *val, void *arg) {    service_t svc = (service_t) val;    jid_free(svc->jid);    xhash_free(svc->features);    free(svc);}static void _disco_free(module_t mod) {    disco_t d = (disco_t) mod->private;    xhash_walk(d->stat, _disco_free_walker, NULL);    xhash_walk(d->dyn, _disco_free_walker, NULL);    xhash_free(d->stat);    xhash_free(d->dyn);    xhash_free(d->un);    if(d->disco_info_result != NULL) pkt_free(d->disco_info_result);    if(d->disco_items_result != NULL) pkt_free(d->disco_items_result);    if(d->agents_result != NULL) pkt_free(d->agents_result);    if(d->browse_result != NULL) pkt_free(d->browse_result);    free(d);}int disco_init(mod_instance_t mi, char *arg){    module_t mod = mi->mod;    disco_t d;    nad_t nad;    int items, item, jid, name, category, type, ns;    service_t svc;    if(mod->init) return 0;    log_debug(ZONE, "disco module init");    d = (disco_t) malloc(sizeof(struct disco_st));    memset(d, 0, sizeof(struct disco_st));    /* new hashes to store the lists in */    d->dyn = xhash_new(51);    d->stat = xhash_new(51);    /* identity */    d->category = config_get_one(mod->mm->sm->config, "discovery.identity.category", 0);    if(d->category == NULL) d->category = "server";    d->type = config_get_one(mod->mm->sm->config, "discovery.identity.type", 0);    if(d->type == NULL) d->type = "im";    d->name = config_get_one(mod->mm->sm->config, "discovery.identity.name", 0);    if(d->name == NULL) d->name = "Jabber IM server";    /* agents compatibility */    d->agents = (int) config_get(mod->mm->sm->config, "discovery.agents");    /* browse compatibility */    /* CODE READERS, NOTE WELL: Browse is very deprecated. Don't use this :) */    d->browse = (int) config_get(mod->mm->sm->config, "discovery.browse");    if(d->agents)        log_debug(ZONE, "agents compat enabled");    if(d->browse)        log_debug(ZONE, "browse compat enabled");        /* our data */    mod->private = (void *) d;        /* our handlers */    mod->pkt_sm = _disco_pkt_sm;    mod->in_sess = _disco_in_sess;    mod->pkt_router = _disco_pkt_router;    mod->free = _disco_free;    nad = mod->mm->sm->config->nad;    /* we support a number of things */    feature_register(mod->mm->sm, uri_DISCO);    if(d->agents)        feature_register(mod->mm->sm, uri_AGENTS);    if(d->browse)        feature_register(mod->mm->sm, uri_BROWSE);    /* populate the static list from the config file */    if((items = nad_find_elem(nad, 0, -1, "discovery", 1)) < 0 || (items = nad_find_elem(nad, items, -1, "items", 1)) < 0)        return 0;    item = nad_find_elem(nad, items, -1, "item", 1);    while(item >= 0)    {        /* jid is required */        jid = nad_find_attr(nad, item, -1, "jid", NULL);        if(jid < 0)        {            item = nad_find_elem(nad, item, -1, "item", 0);            continue;        }        /* new service */        svc = (service_t) malloc(sizeof(struct service_st));        memset(svc, 0, sizeof(struct service_st));        svc->features = xhash_new(13);        svc->jid = jid_new(mod->mm->sm->pc, NAD_AVAL(nad, jid), NAD_AVAL_L(nad, jid));        /* link it in */        xhash_put(d->stat, jid_full(svc->jid), (void *) svc);        /* copy the name */        name = nad_find_attr(nad, item, -1, "name", NULL);        if(name >= 0)            snprintf(svc->name, 257, "%.*s", NAD_AVAL_L(nad, name), NAD_AVAL(nad, name));        /* category and type */        category = nad_find_attr(nad, item, -1, "category", NULL);        if(category >= 0)            snprintf(svc->category, 257, "%.*s", NAD_AVAL_L(nad, category), NAD_AVAL(nad, category));        else            strcpy(svc->category, "unknown");        type = nad_find_attr(nad, item, -1, "type", NULL);        if(type >= 0)            snprintf(svc->type, 257, "%.*s", NAD_AVAL_L(nad, type), NAD_AVAL(nad, type));        else            strcpy(svc->type, "unknown");        /* namespaces */        ns = nad_find_elem(nad, item, -1, "ns", 1);        while(ns >= 0)        {            if(NAD_CDATA_L(nad, ns) > 0)                xhash_put(svc->features, pstrdupx(xhash_pool(svc->features), NAD_CDATA(nad, ns), NAD_CDATA_L(nad, ns)), (void *) 1);            ns = nad_find_elem(nad, ns, -1, "ns", 0);        }        item = nad_find_elem(nad, item, -1, "item", 0);        log_debug(ZONE, "added %s to static list", jid_full(svc->jid));    }    /* generate the initial union list */    _disco_unify_lists(d);    /* we don't generate the packets here, because the router conn isn't up yet, and so we don't have a nad cache */    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -