jabberd2  2.3.3
mod_help.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 /* for strndup */
22 #define _GNU_SOURCE
23 #include <string.h>
24 #include "sm.h"
25 
33 /* XEP-0157 serverinfo fields */
34 static const char *_serverinfo_fields[] = {
35  "abuse-addresses",
36  "admin-addresses",
37  "feedback-addresses",
38  "sales-addresses",
39  "security-addresses",
40  "support-addresses",
41  NULL
42 };
43 
45 {
46  module_t mod = mi->mod;
47  jid_t all, msg, jid, smjid;
48  int subj, subjectl;
49  char *org_subject;
50  char *subject;
51  char *resource = (char *) mod->private;
52 
53  smjid = jid_new(jid_user(pkt->to), -1);
54  jid_reset_components(smjid, smjid->node, smjid->domain, resource);
55 
56  /* answer to probes and subscription requests */
57  if(pkt->type == pkt_PRESENCE_PROBE || pkt->type == pkt_S10N) {
58  log_debug(ZONE, "answering presence probe/sub from %s with /help resource", jid_full(pkt->from));
59 
60  /* send presence */
61  pkt_router(pkt_create(mod->mm->sm, "presence", NULL, jid_user(pkt->from), jid_full(smjid)));
62  }
63 
64  jid_free(smjid);
65 
66  /* we want messages addressed to the sm itself or /help resource */
67  if(!(pkt->type & pkt_MESSAGE) || (pkt->to->resource[0] != '\0' && strcmp(pkt->to->resource, "help")))
68  return mod_PASS;
69 
70  log_debug(ZONE, "help message from %s", jid_full(pkt->from));
71 
72  all = xhash_get(mod->mm->sm->acls, "all");
73  msg = xhash_get(mod->mm->sm->acls, "messages");
74 
75  nad_set_attr(pkt->nad, 1, -1, "type", NULL, 0);
76  subj = nad_find_elem(pkt->nad, 1, NAD_ENS(pkt->nad, 1), "subject", 1);
77  if(subj >= 0 && NAD_CDATA_L(pkt->nad, subj) > 0)
78  {
79  org_subject = strndup(NAD_CDATA(pkt->nad, subj), NAD_CDATA_L(pkt->nad, subj));
80  } else {
81  org_subject = "(none)";
82  }
83  subjectl = strlen(org_subject) + strlen(jid_full(pkt->from)) + 8;
84  subject = (char *) malloc(sizeof(char) * subjectl);
85  snprintf(subject, subjectl, "Fwd[%s]: %s", jid_full(pkt->from), org_subject);
86  if(subj >= 0 && NAD_CDATA_L(pkt->nad, subj) > 0)
87  {
88  free(org_subject);
89  nad_drop_elem(pkt->nad, subj);
90  }
91  nad_insert_elem(pkt->nad, 1, NAD_ENS(pkt->nad, 1), "subject", subject);
92 
93  for(jid = all; jid != NULL; jid = jid->next)
94  {
95  if (jid_compare_full(pkt->from, jid) == 0) {
96  /* make a copy of the nad so it can be dumped to a string */
97  nad_t copy = nad_copy(pkt->nad);
98  const char * xml;
99  int len;
100  if (!copy) {
101  log_write(mod->mm->sm->log, LOG_ERR, "%s:%d help admin %s is messaging sm for help! packet dropped. (unable to print packet - out of memory?)", ZONE, jid_full(jid));
102  continue;
103  }
104  nad_print(copy, 0, &xml, &len);
105  log_write(mod->mm->sm->log, LOG_ERR, "%s:%d help admin %s is messaging sm for help! packet dropped: \"%.*s\"\n", ZONE, jid_full(jid), len, xml);
106  nad_free(copy);
107  continue;
108  }
109  log_debug(ZONE, "resending to %s", jid_full(jid));
110  pkt_router(pkt_dup(pkt, jid_full(jid), jid_user(pkt->to)));
111  }
112 
113  for(jid = msg; jid != NULL; jid = jid->next)
114  if(!jid_search(all, jid))
115  {
116  log_debug(ZONE, "resending to %s", jid_full(jid));
117  pkt_router(pkt_dup(pkt, jid_full(jid), jid_user(pkt->to)));
118  }
119 
120  /* !!! autoreply */
121 
122  free(subject);
123  pkt_free(pkt);
124 
125  return mod_HANDLED;
126 }
127 
129 {
130  module_t mod = mi->mod;
131  int ns, i, n;
132  config_elem_t elem;
133  char confelem[64];
134 
135  log_debug(ZONE, "in mod_help disco-extend");
136 
137  if(config_get(mod->mm->sm->config, "discovery.serverinfo") == NULL)
138  return;
139 
140  ns = nad_add_namespace(pkt->nad, uri_XDATA, NULL);
141  /* there may be several XDATA siblings, so need to enforce the NS */
142  pkt->nad->scope = ns;
143 
144  nad_append_elem(pkt->nad, ns, "x", 3);
145  nad_append_attr(pkt->nad, -1, "type", "result");
146  /* hidden form type field*/
147  nad_append_elem(pkt->nad, -1, "field", 4);
148  nad_append_attr(pkt->nad, -1, "var", "FORM_TYPE");
149  nad_append_attr(pkt->nad, -1, "type", "hidden");
150  nad_append_elem(pkt->nad, -1, "value", 5);
152 
153  /* loop over serverinfo fields */
154  for(i = 0; _serverinfo_fields[i]; i++) {
155  snprintf(confelem, 64, "discovery.serverinfo.%s.value", _serverinfo_fields[i]);
156  elem = config_get(mod->mm->sm->config, confelem);
157 
158  if(elem != NULL) {
159  nad_append_elem(pkt->nad, -1, "field", 4);
160  nad_append_attr(pkt->nad, -1, "var", _serverinfo_fields[i]);
161 
162  for(n = 0; n < elem->nvalues; n++) {
163  log_debug(ZONE, "adding %s: %s", confelem, elem->values[n]);
164  nad_append_elem(pkt->nad, -1, "value", 5);
165  nad_append_cdata(pkt->nad, elem->values[n], strlen(elem->values[n]), 6);
166  }
167  }
168  }
169 }
170 
171 DLLEXPORT int module_init(mod_instance_t mi, const char *arg) {
172  module_t mod = mi->mod;
173 
174  if(mod->init) return 0;
175 
176  /* store /help resource for use when answering probes */
177  mod->private = "help";
178 
179  mod->pkt_sm = _help_pkt_sm;
181  /* module data is static so nothing to free */
182  /* mod->free = _help_free; */
183 
184  return 0;
185 }
pkt_type_t type
packet type
Definition: sm.h:138
Definition: nad.h:93
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val)
attach new attr to the last elem
Definition: nad.c:701
data structures and prototypes for the session manager
int nad_insert_elem(nad_t nad, int parent, int ns, const char *name, const char *cdata)
shove in a new child elem after the given one
Definition: nad.c:405
subscribe request
Definition: sm.h:102
const char ** values
Definition: util.h:209
#define NAD_CDATA_L(N, E)
Definition: nad.h:186
const char * jid_user(jid_t jid)
expand and return the user
Definition: jid.c:339
const char * jid_full(jid_t jid)
expand and return the full
Definition: jid.c:347
jid_t jid_new(const char *id, int len)
make a new jid
Definition: jid.c:81
single instance of a module in a chain
Definition: sm.h:445
#define uri_SERVERINFO
Definition: uri.h:81
log_t log
log context
Definition: sm.h:199
static mod_ret_t _help_pkt_sm(mod_instance_t mi, pkt_t pkt)
Definition: mod_help.c:44
int nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
Definition: nad.c:204
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
Definition: nad.c:709
config_t config
config context
Definition: sm.h:197
int init
number of times the module intialiser has been called
Definition: sm.h:415
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
Definition: nad.c:734
pkt_t pkt_dup(pkt_t pkt, const char *to, const char *from)
duplicate pkt, replacing addresses
Definition: pkt.c:84
char * resource
Definition: jid.h:46
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
Definition: nad.c:667
void nad_free(nad_t nad)
free that nad
Definition: nad.c:178
nad_t nad_copy(nad_t nad)
copy a nad
Definition: nad.c:145
mm_t mm
module manager
Definition: sm.h:403
#define DLLEXPORT
Definition: c2s.h:47
void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen)
create, update, or zap any matching attr on this elem
Definition: nad.c:375
sm_t sm
sm context
Definition: sm.h:365
jid_t jid_reset_components(jid_t jid, const char *node, const char *domain, const char *resource)
build a jid from components
Definition: jid.c:281
module_t mod
module that this is an instance of
Definition: sm.h:448
jid_t from
packet addressing (not used for routing)
Definition: sm.h:140
void * private
module private data
Definition: sm.h:417
packet summary data wrapper
Definition: sm.h:129
int jid_search(jid_t list, jid_t jid)
util to search through jids
Definition: jid.c:413
nad_t nad
nad of the entire packet
Definition: sm.h:146
void jid_free(jid_t jid)
free a jid
Definition: jid.c:286
char * domain
Definition: jid.h:45
Definition: jid.h:42
static const char * _serverinfo_fields[]
Definition: mod_help.c:34
#define uri_XDATA
Definition: uri.h:54
DLLEXPORT int module_init(mod_instance_t mi, const char *arg)
Definition: mod_help.c:171
int jid_compare_full(jid_t a, jid_t b)
compare two full jids
Definition: jid.c:364
void pkt_router(pkt_t pkt)
Definition: pkt.c:379
void pkt_free(pkt_t pkt)
Definition: pkt.c:315
#define log_debug(...)
Definition: log.h:65
packet was unhandled, should be passed to the next module
Definition: sm.h:339
config_elem_t config_get(config_t c, const char *key)
get the config element for this key
Definition: config.c:271
packet was handled (and freed)
Definition: sm.h:338
int scope
Definition: nad.h:107
mod_ret_t(* pkt_sm)(mod_instance_t mi, pkt_t pkt)
pkt-sm handler
Definition: sm.h:428
message
Definition: sm.h:95
jid_t to
Definition: sm.h:140
void nad_drop_elem(nad_t nad, int elem)
remove an element (and its subelements)
Definition: nad.c:452
#define NAD_CDATA(N, E)
Definition: nad.h:185
void * xhash_get(xht h, const char *key)
Definition: xhash.c:184
void(* disco_extend)(mod_instance_t mi, pkt_t pkt)
disco-extend handler
Definition: sm.h:439
xht acls
access control lists (key is list name, value is jid_t list)
Definition: sm.h:214
#define ZONE
Definition: mio_impl.h:76
struct jid_st * next
Definition: jid.h:67
data for a single module
Definition: sm.h:402
static void _help_disco_extend(mod_instance_t mi, pkt_t pkt)
Definition: mod_help.c:128
presence (probe)
Definition: sm.h:101
pkt_t pkt_create(sm_t sm, const char *elem, const char *type, const char *to, const char *from)
Definition: pkt.c:328
a single element
Definition: util.h:207
mod_ret_t
module return values
Definition: sm.h:337
int nvalues
Definition: util.h:210
void nad_print(nad_t nad, int elem, const char **xml, int *len)
create a string representation of the given element (and children), point references to it ...
Definition: nad.c:1164
char * node
Definition: jid.h:44
#define NAD_ENS(N, E)
Definition: nad.h:196