📄 mod_privacy.c
字号:
else if(NAD_AVAL_L(pkt->nad, type) == 5 && strncmp("group", NAD_AVAL(pkt->nad, type), 5) == 0) { zitem->type = zebra_GROUP; zitem->group = pstrdupx(zlist->p, NAD_AVAL(pkt->nad, value), NAD_AVAL_L(pkt->nad, value)); /* !!! check if the group exists */ log_debug(ZONE, "group item with value '%s'", zitem->group); os_object_put(o, "type", "group", os_type_STRING); os_object_put(o, "value", zitem->group, os_type_STRING); } else if(NAD_AVAL_L(pkt->nad, type) == 12 && strncmp("subscription", NAD_AVAL(pkt->nad, type), 12) == 0) { zitem->type = zebra_S10N; os_object_put(o, "type", "subscription", os_type_STRING); if(NAD_AVAL_L(pkt->nad, value) == 2 && strncmp("to", NAD_AVAL(pkt->nad, value), 2) == 0) { zitem->to = 1; os_object_put(o, "value", "to", os_type_STRING); } else if(NAD_AVAL_L(pkt->nad, value) == 4 && strncmp("from", NAD_AVAL(pkt->nad, value), 4) == 0) { zitem->from = 1; os_object_put(o, "value", "from", os_type_STRING); } else if(NAD_AVAL_L(pkt->nad, value) == 4 && strncmp("both", NAD_AVAL(pkt->nad, value), 4) == 0) { zitem->to = zitem->from = 1; os_object_put(o, "value", "both", os_type_STRING); } else if(NAD_AVAL_L(pkt->nad, value) == 4 && strncmp("none", NAD_AVAL(pkt->nad, value), 4) == 0) os_object_put(o, "value", "none", os_type_STRING); else { log_debug(ZONE, "invalid value '%.*s' on s10n item, failing request", NAD_AVAL_L(pkt->nad, value), NAD_AVAL(pkt->nad, value)); pool_free(p); os_free(os); return -stanza_err_BAD_REQUEST; } log_debug(ZONE, "s10n item with value '%.*s' (to %d from %d)", NAD_AVAL_L(pkt->nad, value), NAD_AVAL(pkt->nad, value), zitem->to, zitem->from); } } /* action */ if(NAD_AVAL_L(pkt->nad, action) == 4 && strncmp("deny", NAD_AVAL(pkt->nad, action), 4) == 0) { zitem->deny = 1; log_debug(ZONE, "deny rule"); } else if(NAD_AVAL_L(pkt->nad, action) == 5 && strncmp("allow", NAD_AVAL(pkt->nad, action), 5) == 0) { zitem->deny = 0; log_debug(ZONE, "allow rule"); } else { log_debug(ZONE, "unknown action '%.*s', failing request", NAD_AVAL_L(pkt->nad, action), NAD_AVAL(pkt->nad, action)); pool_free(p); os_free(os); return -stanza_err_BAD_REQUEST; } os_object_put(o, "deny", &zitem->deny, os_type_BOOLEAN); /* order */ snprintf(corder, 14, "%.*s", NAD_AVAL_L(pkt->nad, order), NAD_AVAL(pkt->nad, order)); corder[13] = '\0'; zitem->order = atoi(corder); os_object_put(o, "order", &zitem->order, os_type_INTEGER); /* block types */ if(nad_find_elem(pkt->nad, item, ns, "message", 1) >= 0) zitem->block |= block_MESSAGE; if(nad_find_elem(pkt->nad, item, ns, "presence-in", 1) >= 0) zitem->block |= block_PRES_IN; if(nad_find_elem(pkt->nad, item, ns, "presence-out", 1) >= 0) zitem->block |= block_PRES_OUT; if(nad_find_elem(pkt->nad, item, ns, "iq", 1) >= 0) zitem->block |= block_IQ; os_object_put(o, "block", &zitem->block, os_type_INTEGER); /* insert it */ for(scan = zlist->items; scan != NULL; scan = scan->next) if(zitem->order < scan->order) break; /* we're >= everyone, add us to the end */ if(scan == NULL) { if(zlist->last == NULL) zlist->items = zlist->last = zitem; else { zlist->last->next = zitem; zitem->prev = zlist->last; zlist->last = zitem; } } /* insert just before scan */ else { if(zlist->items == scan) { zitem->next = zlist->items; zlist->items = zitem; scan->prev = zitem; } else { zitem->next = scan; zitem->prev = scan->prev; scan->prev->next = zitem; scan->prev = zitem; } } /* next item */ item = nad_find_elem(pkt->nad, item, ns, "item", 0); } /* write the whole list out */ sprintf(filter, "(list=%i:%s)", strlen(zlist->name), zlist->name); ret = storage_replace(mod->mm->sm->st, "privacy-items", jid_user(sess->user->jid), filter, os); os_free(os); /* failed! */ if(ret != st_SUCCESS) { pool_free(zlist->p); return -stanza_err_INTERNAL_SERVER_ERROR; } /* old list pointer */ old = xhash_get(z->lists, zlist->name); /* removed list */ if(zlist->items == NULL) { log_debug(ZONE, "removed list %s", zlist->name); xhash_zap(z->lists, zlist->name); pool_free(zlist->p); if(old != NULL) pool_free(old->p); zlist = NULL; } else { log_debug(ZONE, "updated list %s", zlist->name); xhash_put(z->lists, zlist->name, (void *) zlist); if(old != NULL) pool_free(old->p); } /* if this was a new list, then noone has it active yet */ if(old != NULL) { /* relink */ log_debug(ZONE, "relinking sessions"); /* loop through sessions, relink */ for(sscan = sess->user->sessions; sscan != NULL; sscan = sscan->next) if(sscan->module_data[mod->index] == old) { sscan->module_data[mod->index] = (void *) zlist; log_debug(ZONE, "session '%s' now has active list '%s'", jid_full(sscan->jid), (zlist != NULL) ? zlist->name : "(NONE)"); } /* default list */ if(z->def == old) { z->def = zlist; if(zlist == NULL) { storage_delete(mod->mm->sm->st, "privacy-default", jid_user(sess->user->jid), NULL); log_debug(ZONE, "removed default list"); } else { os = os_new(); o = os_object_new(os); os_object_put(o, "default", zlist->name, os_type_STRING); storage_replace(mod->mm->sm->st, "privacy-default", jid_user(sess->user->jid), NULL, os); os_free(os); log_debug(ZONE, "default list is now '%s'", (zlist != NULL) ? zlist->name : "(NONE)"); } } } } /* set the active list */ if(active >= 0) { name = nad_find_attr(pkt->nad, active, -1, "name", NULL); if(name < 0) { /* no name, no active list */ log_debug(ZONE, "clearing active list for session '%s'", jid_full(sess->jid)); sess->module_data[mod->index] = NULL; } else { snprintf(str, 256, "%.*s", NAD_AVAL_L(pkt->nad, name), NAD_AVAL(pkt->nad, name)); str[255] = '\0'; zlist = xhash_get(z->lists, str); if(zlist == NULL) { log_debug(ZONE, "request to make list '%s' active, but there's no such list", str); /* hack the error in */ pkt_error(pkt, stanza_err_ITEM_NOT_FOUND); pkt_sess(pkt, sess); return mod_HANDLED; } sess->module_data[mod->index] = zlist; log_debug(ZONE, "session '%s' now has active list '%s'", jid_full(sess->jid), str); } } /* set the default list */ if(def >= 0) { name = nad_find_attr(pkt->nad, def, -1, "name", NULL); if(name < 0) { /* no name, no default list */ log_debug(ZONE, "clearing default list for '%s'", jid_user(sess->user->jid)); z->def = NULL; } else { snprintf(str, 256, "%.*s", NAD_AVAL_L(pkt->nad, name), NAD_AVAL(pkt->nad, name)); str[255] = '\0'; zlist = xhash_get(z->lists, str); if(zlist == NULL) { log_debug(ZONE, "request to make list '%s' default, but there's no such list"); /* hack the error in */ pkt_error(pkt, stanza_err_ITEM_NOT_FOUND); pkt_sess(pkt, sess); return mod_HANDLED; } z->def = zlist; os = os_new(); o = os_object_new(os); os_object_put(o, "default", zlist->name, os_type_STRING); storage_replace(mod->mm->sm->st, "privacy-default", jid_user(sess->user->jid), NULL, os); os_free(os); log_debug(ZONE, "'%s' now has default list '%s'", jid_user(sess->user->jid), str); } } /* done, let them know */ result = pkt_create(pkt->sm, "iq", "result", NULL, NULL); pkt_id(pkt, result); /* done with this */ pkt_free(pkt); /* give it to the session */ pkt_sess(result, sess); /* all done */ return mod_HANDLED; } /* its a get */ /* only allowed to request one list, if any */ list = nad_find_elem(pkt->nad, query, ns, "list", 1); if(list >= 0 && nad_find_elem(pkt->nad, list, ns, "list", 0) >= 0) { /* hack the error in */ pkt_error(pkt, stanza_err_BAD_REQUEST); pkt_sess(pkt, sess); return mod_HANDLED; } result = pkt_create(pkt->sm, "iq", "result", NULL, NULL); pkt_id(pkt, result); ns = nad_add_namespace(result->nad, uri_PRIVACY, NULL); query = nad_insert_elem(result->nad, 1, ns, "query", NULL); /* just do one */ if(list >= 0) { name = nad_find_attr(pkt->nad, list, -1, "name", NULL); zlist = xhash_getx(z->lists, NAD_AVAL(pkt->nad, name), NAD_AVAL_L(pkt->nad, name)); if(zlist == NULL) { /* hack the error in */ pkt_error(pkt, stanza_err_ITEM_NOT_FOUND); pkt_sess(pkt, sess); return mod_HANDLED; } _privacy_result_builder(z->lists, zlist->name, (void *) zlist, (void *) result); } else { /* walk the list hash and add the lists in */ xhash_walk(z->lists, _privacy_lists_result_builder, (void *) result); } /* tell them about current active and default list if they asked for everything */ if(list < 0) { /* active */ if(sess->module_data[mod->index] != NULL) { active = nad_insert_elem(result->nad, query, ns, "active", NULL); nad_set_attr(result->nad, active, -1, "name", ((zebra_list_t) sess->module_data[mod->index])->name, 0); } /* and the default list */ if(z->def != NULL) { def = nad_insert_elem(result->nad, query, ns, "default", NULL); nad_set_attr(result->nad, def, -1, "name", z->def->name, 0); } } /* give it to the session */ pkt_sess(result, sess); /* done with this */ pkt_free(pkt); /* all done */ return mod_HANDLED;}static void _privacy_user_delete(mod_instance_t mi, jid_t jid) { log_debug(ZONE, "deleting privacy data for %s", jid_user(jid)); storage_delete(mi->sm->st, "privacy-items", jid_user(jid), NULL); storage_delete(mi->sm->st, "privacy-default", jid_user(jid), NULL);}int privacy_init(mod_instance_t mi, char *arg) { module_t mod = mi->mod; if(mod->init) return 0; mod->user_load = _privacy_user_load; mod->in_router = _privacy_in_router; mod->out_router = _privacy_out_router; mod->in_sess = _privacy_in_sess; mod->user_delete = _privacy_user_delete; feature_register(mod->mm->sm, uri_PRIVACY); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -