mod_iq_vcard.c

来自「这是一个完全开放的」· C语言 代码 · 共 291 行

C
291
字号
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, *                    Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA */#include "sm.h"/** @file sm/mod_iq_vcard.c  * @brief user profiles (vcard)  * @author Robert Norris  * $Date: 2004/11/13 16:08:33 $  * $Revision: 1.19.2.2 $  *//** * these are the vcard attributes that gabber supports. they're also * all strings, and thus easy to automate. there might be more in * regular use, we need to check that out. one day, when we're all * using real foaf profiles, we'll have bigger things to worry about :) */static char *_iq_vcard_map[] = {    "FN",           "fn",    "NICKNAME",     "nickname",    "URL",          "url",    "TEL/NUMBER",   "tel",    "EMAIL/USERID", "email",    "TITLE",        "title",    "ROLE",         "role",    "BDAY",         "bday",    "DESC",         "desc",    "N/GIVEN",      "n-given",    "N/FAMILY",     "n-family",    "ADR/STREET",   "adr-street",    "ADR/EXTADD",   "adr-extadd",    "ADR/LOCALITY", "adr-locality",    "ADR/REGION",   "adr-region",    "ADR/PCODE",    "adr-pcode",    "ADR/CTRY",     "adr-country",    "ORG/ORGNAME",  "org-orgname",    "ORG/ORGUNIT",  "org-orgunit",    NULL,           NULL};static os_t _iq_vcard_to_object(pkt_t pkt) {    os_t os;    os_object_t o;    int i = 0, elem;    char *vkey, *dkey, *vskey, ekey[10], cdata[4096];    log_debug(ZONE, "building object from packet");    os = os_new();    o = os_object_new(os);        while(_iq_vcard_map[i] != NULL) {        vkey = _iq_vcard_map[i];        dkey = _iq_vcard_map[i + 1];        i += 2;        vskey = strchr(vkey, '/');        if(vskey == NULL) {            vskey = vkey;            elem = 2;        } else {            sprintf(ekey, "%.*s", vskey - vkey, vkey);            elem = nad_find_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 2), ekey, 1);            if(elem < 0)                continue;            vskey++;        }        elem = nad_find_elem(pkt->nad, elem, NAD_ENS(pkt->nad, 2), vskey, 1);        if(elem < 0 || NAD_CDATA_L(pkt->nad, elem) == 0)            continue;        log_debug(ZONE, "extracted vcard key %s val '%.*s' for db key %s", vkey, NAD_CDATA_L(pkt->nad, elem), NAD_CDATA(pkt->nad, elem), dkey);        snprintf(cdata, 4096, "%.*s", NAD_CDATA_L(pkt->nad, elem), NAD_CDATA(pkt->nad, elem));        cdata[4095] = '\0';        os_object_put(o, dkey, cdata, os_type_STRING);    }    return os;}static pkt_t _iq_vcard_to_pkt(sm_t sm, os_t os) {    pkt_t pkt;    os_object_t o;    int i = 0, elem;    char *vkey, *dkey, *vskey, ekey[10], *dval;    os_type_t ot;        log_debug(ZONE, "building packet from object");    pkt = pkt_create(sm, "iq", "result", NULL, NULL);    nad_append_elem(pkt->nad, nad_add_namespace(pkt->nad, "vcard-temp", NULL), "vCard", 2);    if(!os_iter_first(os))        return pkt;    o = os_iter_object(os);    while(_iq_vcard_map[i] != NULL) {        vkey = _iq_vcard_map[i];        dkey = _iq_vcard_map[i + 1];        i += 2;        if(!os_object_get(os, o, dkey, (void **) &dval, os_type_STRING, &ot))            continue;        vskey = strchr(vkey, '/');        if(vskey == NULL) {            vskey = vkey;            elem = 2;        } else {            sprintf(ekey, "%.*s", vskey - vkey, vkey);            elem = nad_find_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 2), ekey, 1);            if(elem < 0)                elem = nad_append_elem(pkt->nad, NAD_ENS(pkt->nad, 2), ekey, 3);            vskey++;        }        log_debug(ZONE, "extracted dbkey %s val '%s' for vcard key %s", dkey, dval, vkey);        nad_append_elem(pkt->nad, NAD_ENS(pkt->nad, 2), vskey, pkt->nad->elems[elem].depth + 1);        nad_append_cdata(pkt->nad, dval, strlen(dval), pkt->nad->elems[elem].depth + 2);    }    return pkt;}static mod_ret_t _iq_vcard_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) {    os_t os;    st_ret_t ret;    pkt_t result;    /* only handle vcard sets and gets that aren't to anyone */    if(pkt->to != NULL || (pkt->type != pkt_IQ && pkt->type != pkt_IQ_SET) || pkt->ns != ns_VCARD)        return mod_PASS;    /* get */    if(pkt->type == pkt_IQ) {        ret = storage_get(sess->user->sm->st, "vcard", jid_user(sess->jid), NULL, &os);        switch(ret) {            case st_FAILED:                return -stanza_err_INTERNAL_SERVER_ERROR;            case st_NOTIMPL:                return -stanza_err_FEATURE_NOT_IMPLEMENTED;            case st_NOTFOUND:                nad_set_attr(pkt->nad, 1, -1, "type", "result", 6);                nad_set_attr(pkt->nad, 1, -1, "to", NULL, 0);                nad_set_attr(pkt->nad, 1, -1, "from", NULL, 0);                pkt_sess(pkt, sess);                return mod_HANDLED;            case st_SUCCESS:                result = _iq_vcard_to_pkt(sess->user->sm, os);                os_free(os);                nad_set_attr(result->nad, 1, -1, "type", "result", 6);                pkt_id(pkt, result);                pkt_sess(result, sess);                pkt_free(pkt);                return mod_HANDLED;        }        /* we never get here */        pkt_free(pkt);        return mod_HANDLED;    }    os = _iq_vcard_to_object(pkt);    ret = storage_replace(sess->user->sm->st, "vcard", jid_user(sess->jid), NULL, os);    os_free(os);    switch(ret) {        case st_FAILED:            return -stanza_err_INTERNAL_SERVER_ERROR;        case st_NOTIMPL:            return -stanza_err_FEATURE_NOT_IMPLEMENTED;        default:            result = pkt_create(sess->user->sm, "iq", "result", NULL, NULL);            pkt_id(pkt, result);            pkt_sess(result, sess);                        pkt_free(pkt);            return mod_HANDLED;    }    /* we never get here */    pkt_free(pkt);    return mod_HANDLED;}static mod_ret_t _iq_vcard_pkt_user(mod_instance_t mi, user_t user, pkt_t pkt) {    os_t os;    st_ret_t ret;    pkt_t result;    /* only handle vcard sets and gets */    if((pkt->type != pkt_IQ && pkt->type != pkt_IQ_SET) || pkt->ns != ns_VCARD)        return mod_PASS;    /* error them if they're trying to do a set */    if(pkt->type == pkt_IQ_SET)        return -stanza_err_FORBIDDEN;    ret = storage_get(user->sm->st, "vcard", jid_user(user->jid), NULL, &os);    switch(ret) {        case st_FAILED:            return -stanza_err_INTERNAL_SERVER_ERROR;        case st_NOTIMPL:            return -stanza_err_FEATURE_NOT_IMPLEMENTED;        case st_NOTFOUND:            return -stanza_err_ITEM_NOT_FOUND;        case st_SUCCESS:            result = _iq_vcard_to_pkt(user->sm, os);            os_free(os);            result->to = jid_dup(pkt->from);            result->from = jid_dup(pkt->to);            nad_set_attr(result->nad, 1, -1, "to", jid_full(result->to), 0);            nad_set_attr(result->nad, 1, -1, "from", jid_full(result->from), 0);            pkt_id(pkt, result);            pkt_router(result);            pkt_free(pkt);            return mod_HANDLED;    }    /* we never get here */    pkt_free(pkt);    return mod_HANDLED;}static void _iq_vcard_user_delete(mod_instance_t mi, jid_t jid) {    log_debug(ZONE, "deleting vcard for %s", jid_user(jid));    storage_delete(mi->sm->st, "vcard", jid_user(jid), NULL);}int iq_vcard_init(mod_instance_t mi, char *arg) {    module_t mod = mi->mod;    if(mod->init) return 0;    mod->in_sess = _iq_vcard_in_sess;    mod->pkt_user = _iq_vcard_pkt_user;    mod->user_delete = _iq_vcard_user_delete;    feature_register(mod->mm->sm, "vcard-temp");    return 0;}

⌨️ 快捷键说明

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