📄 jid.c
字号:
/* * 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 "util.h"#ifdef HAVE_IDN#include <stringprep.h>#endif/** preparation cache */prep_cache_t prep_cache_new(void) {#ifdef HAVE_IDN prep_cache_t pc; pc = (prep_cache_t) malloc(sizeof(struct prep_cache_st)); memset(pc, 0, sizeof(struct prep_cache_st)); pc->node = xhash_new(301); pc->domain = xhash_new(301); pc->resource = xhash_new(301); return pc;#else return NULL;#endif}void prep_cache_free(prep_cache_t pc) {#ifdef HAVE_IDN xhash_free(pc->node); xhash_free(pc->domain); xhash_free(pc->resource); free(pc);#endif}char *prep_cache_node_get(prep_cache_t pc, char *from) { return (char *) xhash_get(pc->node, from);}void prep_cache_node_set(prep_cache_t pc, char *from, char *to) { xhash_put(pc->node, pstrdup(xhash_pool(pc->node), from), (void *) pstrdup(xhash_pool(pc->node), to));}char *prep_cache_domain_get(prep_cache_t pc, char *from) { return (char *) xhash_get(pc->domain, from);}void prep_cache_domain_set(prep_cache_t pc, char *from, char *to) { xhash_put(pc->domain, pstrdup(xhash_pool(pc->domain), from), (void *) pstrdup(xhash_pool(pc->domain), to));}char *prep_cache_resource_get(prep_cache_t pc, char *from) { return (char *) xhash_get(pc->resource, from);}void prep_cache_resource_set(prep_cache_t pc, char *from, char *to) { xhash_put(pc->resource, pstrdup(xhash_pool(pc->resource), from), (void *) pstrdup(xhash_pool(pc->resource), to));}/** do stringprep on the pieces */int jid_prep(jid_t jid) {#ifdef HAVE_IDN char str[1024], *prep; jid->dirty = 1; /* no cache, so do a real prep */ if(jid->pc == NULL) { if(jid->node[0] != '\0') if(stringprep_xmpp_nodeprep(jid->node, 1024) != 0) return 1; if(stringprep_nameprep(jid->domain, 1024) != 0) return 1; if(jid->resource[0] != '\0') if(stringprep_xmpp_resourceprep(jid->node, 1024) != 0) return 1; return 0; } /* cache version */ if(jid->node[0] != '\0') { strcpy(str, jid->node); prep = prep_cache_node_get(jid->pc, str); if(prep != NULL) strcpy(jid->node, prep); else { if(stringprep_xmpp_nodeprep(str, 1024) != 0) return 1; prep_cache_node_set(jid->pc, jid->node, str); strcpy(jid->node, str); } } strcpy(str, jid->domain); prep = prep_cache_domain_get(jid->pc, str); if(prep != NULL) strcpy(jid->domain, prep); else { if(stringprep_nameprep(str, 1024) != 0) return 1; prep_cache_domain_set(jid->pc, jid->domain, str); strcpy(jid->domain, str); } if(jid->resource[0] != '\0') { strcpy(str, jid->resource); prep = prep_cache_resource_get(jid->pc, str); if(prep != NULL) strcpy(jid->resource, prep); else { if(stringprep_xmpp_resourceprep(str, 1024) != 0) return 1; prep_cache_resource_set(jid->pc, jid->resource, str); strcpy(jid->resource, str); } }#endif return 0;}/** make a new jid */jid_t jid_new(prep_cache_t pc, const unsigned char *id, int len) { jid_t jid, ret; jid = malloc(sizeof(struct jid_st)); jid->pc = pc; ret = jid_reset(jid, id, len); if(ret == NULL) free(jid); return ret;}/** build a jid from an id */jid_t jid_reset(jid_t jid, const unsigned char *id, int len) { prep_cache_t pc; unsigned char *myid, *cur; assert((int) jid); pc = jid->pc; memset(jid, 0, sizeof(struct jid_st)); jid->pc = pc; /* nice empty jid */ if(id == NULL) return jid; if(len == 0) len = strlen(id); myid = (char *) malloc(sizeof(char) * (len + 1)); sprintf(myid, "%.*s", len, id); /* get the resource first */ cur = strstr(myid, "/"); if(cur != NULL) { *cur = '\0'; cur++; if(strlen(cur) > 0) strncpy(jid->resource, cur, 1024); } /* find the domain */ cur = strstr(myid, "@"); if(cur != NULL) { *cur = '\0'; cur++; if(strlen(cur) == 0) { /* no domain part, bail out */ free(myid); return NULL; } strncpy(jid->domain, cur, 1024); strncpy(jid->node, myid, 1024); } /* no @, so its a domain only */ else strncpy(jid->domain, myid, 1024); free(myid); if(jid_prep(jid) != 0) return NULL; jid->dirty = 1; return jid;}/** free a jid */void jid_free(jid_t jid){ free(jid->_user); free(jid->_full); free(jid);}/** build user and full if they're out of date */void jid_expand(jid_t jid){ int nlen, dlen, rlen, ulen; if(!jid->dirty || *jid->domain == '\0') return; nlen = strlen(jid->node); dlen = strlen(jid->domain); rlen = strlen(jid->resource); if(nlen == 0) { ulen = dlen+1; jid->_user = (unsigned char*) realloc(jid->_user, ulen); strcpy(jid->_user, jid->domain); } else { ulen = nlen+1+dlen+1; jid->_user = (unsigned char*) realloc(jid->_user, ulen); snprintf(jid->_user, ulen, "%s@%s", jid->node, jid->domain); } if(rlen == 0) { jid->_full = (unsigned char*) realloc(jid->_full, ulen); strcpy(jid->_full, jid->_user); } else { jid->_full = (unsigned char*) realloc(jid->_full, ulen+1+rlen); snprintf(jid->_full, ulen+1+rlen, "%s/%s", jid->_user, jid->resource); } jid->dirty = 0;}/** expand and return the user */const unsigned char *jid_user(jid_t jid){ jid_expand(jid); return jid->_user;}/** expand and return the full */const unsigned char *jid_full(jid_t jid){ jid_expand(jid); return jid->_full;}/** compare the user portion of two jids */int jid_compare_user(jid_t a, jid_t b){ jid_expand(a); jid_expand(b); return strcmp(a->_user, b->_user);}/** compare two full jids */int jid_compare_full(jid_t a, jid_t b){ jid_expand(a); jid_expand(b); return strcmp(a->_full, b->_full);}/** duplicate a jid */jid_t jid_dup(jid_t jid){ jid_t new; new = (jid_t) malloc(sizeof(struct jid_st)); memcpy(new, jid, sizeof(struct jid_st)); if(jid->_user) new->_user = strdup(jid->_user); if(jid->_full) new->_full = strdup(jid->_full); return new;}/** util to search through jids */int jid_search(jid_t list, jid_t jid){ jid_t cur; for(cur = list; cur != NULL; cur = cur->next) if(jid_compare_full(cur,jid) == 0) return 1; return 0;}/** remove a jid_t from a list, returning the new list */jid_t jid_zap(jid_t list, jid_t jid){ jid_t cur, dead; if(jid == NULL || list == NULL) return NULL; /* check first */ if(jid_compare_full(jid,list) == 0) { cur = list->next; jid_free(list); return cur; } /* check through the list, stopping at the previous list entry to a matching one */ cur = list; while(cur != NULL) { if(cur->next == NULL) /* none match, so we're done */ return list; if(jid_compare_full(cur->next, jid) == 0) { /* match, kill it */ dead = cur->next; cur->next = cur->next->next; jid_free(dead); return list; } /* loop */ cur = cur->next; } /* shouldn't get here */ return list;}/** make a copy of jid, link into list (avoiding dups) */jid_t jid_append(jid_t list, jid_t jid){ jid_t scan; if(list == NULL) return jid_dup(jid); scan = list; while(scan != NULL) { /* check for dups */ if(jid_compare_full(scan, jid) == 0) return list; /* tack it on to the end of the list */ if(scan->next == NULL) { scan->next = jid_dup(jid); return list; } scan = scan->next; } return list;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -