jabberd2
2.2.17
Main Page
Data Structures
Files
File List
Globals
sm
mod_template_roster.c
Go to the documentation of this file.
1
/*
2
* jabberd - Jabber Open Source Server
3
* Copyright (c) 2002-2003 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
#include "
sm.h
"
22
30
/* user template - roster */
31
32
typedef
struct
_template_roster_st
{
33
sm_t
sm
;
34
char
*
filename
;
35
time_t
mtime
;
36
xht
items
;
37
} *
template_roster_t
;
38
39
/* union for xhash_iter_get to comply with strict-alias rules for gcc3 */
40
union
xhashv
41
{
42
void
**
val
;
43
item_t
*
item_val
;
44
};
45
46
static
int
_template_roster_reload
(
template_roster_t
tr) {
47
struct
stat st;
48
FILE *f;
49
long
size;
50
char
*buf;
51
nad_t
nad;
52
int
nitems, eitem, ajid, as10n, aname, egroup;
53
item_t
item;
54
55
if
(stat(tr->
filename
, &st) < 0) {
56
log_write
(tr->
sm
->
log
, LOG_ERR,
"couldn't stat roster template %s: %s"
, tr->
filename
, strerror(errno));
57
return
1;
58
}
59
60
if
(st.st_mtime <= tr->
mtime
)
61
return
0;
62
63
tr->
mtime
= st.st_mtime;
64
65
if
(tr->
items
!= NULL)
66
xhash_free
(tr->
items
);
67
68
tr->
items
=
xhash_new
(101);
69
70
f = fopen(tr->
filename
,
"r"
);
71
if
(f == NULL) {
72
log_write
(tr->
sm
->
log
, LOG_ERR,
"couldn't open roster template %s: %s"
, tr->
filename
, strerror(errno));
73
return
1;
74
}
75
76
fseek(f, 0, SEEK_END);
77
size = ftell(f);
78
fseek(f, 0, SEEK_SET);
79
80
buf = (
char
*) malloc(
sizeof
(
char
) * size);
81
82
if
(fread(buf, 1, size, f) != size || ferror(f)) {
83
log_write
(tr->
sm
->
log
, LOG_ERR,
"couldn't read from roster template %s: %s"
, tr->
filename
, strerror(errno));
84
free(buf);
85
fclose(f);
86
return
1;
87
}
88
89
fclose(f);
90
91
nad =
nad_parse
(buf, size);
92
if
(nad == NULL) {
93
log_write
(tr->
sm
->
log
, LOG_ERR,
"couldn't parse roster template"
);
94
free(buf);
95
return
1;
96
}
97
98
free(buf);
99
100
if
(nad->
ecur
< 2) {
101
log_write
(tr->
sm
->
log
, LOG_NOTICE,
"roster template has no elements"
);
102
}
103
104
nitems = 0;
105
eitem =
nad_find_elem
(nad, 0,
NAD_ENS
(nad, 0),
"item"
, 1);
106
while
(eitem >= 0) {
107
ajid =
nad_find_attr
(nad, eitem, -1,
"jid"
, NULL);
108
if
(ajid < 0) {
109
log_write
(tr->
sm
->
log
, LOG_ERR,
"roster template has item with no jid, skipping"
);
110
continue
;
111
}
112
113
item = (
item_t
)
pmalloco
(
xhash_pool
(tr->
items
),
sizeof
(
struct
item_st
));
114
115
item->
jid
=
jid_new
(
NAD_AVAL
(nad, ajid),
NAD_AVAL_L
(nad, ajid));
116
if
(item->
jid
== NULL) {
117
log_write
(tr->
sm
->
log
, LOG_ERR,
"roster template has item with invalid jid, skipping"
);
118
continue
;
119
}
120
pool_cleanup
(
xhash_pool
(tr->
items
), (void (*)(
void
*))
jid_free
, item->
jid
);
121
122
as10n =
nad_find_attr
(nad, eitem, -1,
"subscription"
, NULL);
123
if
(as10n >= 0) {
124
if
(
NAD_AVAL_L
(nad, as10n) == 2 && strncmp(
"to"
,
NAD_AVAL
(nad, as10n), 2) == 0)
125
item->
to
= 1;
126
else
if
(
NAD_AVAL_L
(nad, as10n) == 4 && strncmp(
"from"
,
NAD_AVAL
(nad, as10n), 4) == 0)
127
item->
from
= 1;
128
else
if
(
NAD_AVAL_L
(nad, as10n) == 4 && strncmp(
"both"
,
NAD_AVAL
(nad, as10n), 4) == 0)
129
item->
to
= item->
from
= 1;
130
}
131
132
aname =
nad_find_attr
(nad, eitem, -1,
"name"
, NULL);
133
if
(aname >= 0)
134
item->
name
=
pstrdupx
(
xhash_pool
(tr->
items
),
NAD_AVAL
(nad, aname),
NAD_AVAL_L
(nad, aname));
135
136
egroup =
nad_find_elem
(nad, eitem,
NAD_ENS
(nad, 0),
"group"
, 1);
137
while
(egroup >= 0) {
138
if
(
NAD_CDATA_L
(nad, egroup) <= 0) {
139
log_write
(tr->
sm
->
log
, LOG_ERR,
"roster template has zero-length group, skipping"
);
140
continue
;
141
}
142
143
item->
groups
= (
char
**) realloc(item->
groups
,
sizeof
(
char
*) * (item->
ngroups
+ 1));
144
item->
groups
[item->
ngroups
] =
pstrdupx
(
xhash_pool
(tr->
items
),
NAD_CDATA
(nad, egroup),
NAD_CDATA_L
(nad, egroup));
145
item->
ngroups
++;
146
147
egroup =
nad_find_elem
(nad, egroup,
NAD_ENS
(nad, 0),
"group"
, 0);
148
}
149
150
if
(item->
groups
!= NULL)
151
pool_cleanup
(
xhash_pool
(tr->
items
), free, item->
groups
);
152
153
xhash_put
(tr->
items
,
jid_full
(item->
jid
), item);
154
155
log_debug
(
ZONE
,
"loaded roster template item %s, %d groups"
,
jid_full
(item->
jid
), item->
ngroups
);
156
157
nitems++;
158
159
eitem =
nad_find_elem
(nad, eitem,
NAD_ENS
(nad, 0),
"item"
, 0);
160
}
161
162
log_write
(tr->
sm
->
log
, LOG_NOTICE,
"loaded %d items from roster template"
, nitems);
163
164
return
0;
165
}
166
168
static
void
_template_roster_save_item
(
sm_t
sm
,
jid_t
jid
,
item_t
item) {
169
os_t os;
170
os_object_t o;
171
char
filter[4096];
172
int
i;
173
174
log_debug
(
ZONE
,
"saving roster item %s for %s"
,
jid_full
(item->
jid
),
jid_user
(jid));
175
176
os = os_new();
177
o = os_object_new(os);
178
179
os_object_put(o,
"jid"
,
jid_full
(item->
jid
), os_type_STRING);
180
181
if
(item->
name
!= NULL)
182
os_object_put(o,
"name"
, item->
name
, os_type_STRING);
183
184
os_object_put(o,
"to"
, &item->
to
, os_type_BOOLEAN);
185
os_object_put(o,
"from"
, &item->
from
, os_type_BOOLEAN);
186
os_object_put(o,
"ask"
, &item->
ask
, os_type_INTEGER);
187
188
snprintf(filter, 4096,
"(jid=%zu:%s)"
, strlen(
jid_full
(item->
jid
)),
jid_full
(item->
jid
));
189
190
storage_replace(sm->
st
,
"roster-items"
,
jid_user
(jid), filter, os);
191
192
os_free(os);
193
194
snprintf(filter, 4096,
"(jid=%zu:%s)"
, strlen(
jid_full
(item->
jid
)),
jid_full
(item->
jid
));
195
196
if
(item->
ngroups
== 0) {
197
storage_delete(sm->
st
,
"roster-groups"
,
jid_user
(jid), filter);
198
return
;
199
}
200
201
os = os_new();
202
203
for
(i = 0; i < item->
ngroups
; i++) {
204
o = os_object_new(os);
205
206
os_object_put(o,
"jid"
,
jid_full
(item->
jid
), os_type_STRING);
207
os_object_put(o,
"group"
, item->
groups
[i], os_type_STRING);
208
}
209
210
storage_replace(sm->
st
,
"roster-groups"
,
jid_user
(jid), filter, os);
211
212
os_free(os);
213
}
214
215
static
int
_template_roster_user_create
(
mod_instance_t
mi,
jid_t
jid
) {
216
template_roster_t
tr = (
template_roster_t
) mi->
mod
->
private
;
217
item_t
item;
218
union
xhashv
xhv;
219
220
if
(
_template_roster_reload
(tr) != 0)
221
return
0;
222
223
log_debug
(
ZONE
,
"populating roster with items from template"
);
224
225
if
(
xhash_iter_first
(tr->
items
))
226
do
{
227
xhv.item_val = &item;
228
xhash_iter_get
(tr->
items
, NULL, NULL, xhv.val);
229
230
_template_roster_save_item
(tr->
sm
, jid, item);
231
}
while
(
xhash_iter_next
(tr->
items
));
232
233
return
0;
234
}
235
236
static
void
_template_roster_free
(
module_t
mod) {
237
template_roster_t
tr = (
template_roster_t
) mod->
private
;
238
239
if
(tr->
items
!= NULL)
240
xhash_free
(tr->
items
);
241
242
free(tr);
243
}
244
245
DLLEXPORT
int
module_init
(
mod_instance_t
mi,
char
*arg) {
246
module_t
mod = mi->
mod
;
247
char
*filename;
248
template_roster_t
tr;
249
250
if
(mod->
init
)
return
0;
251
252
filename =
config_get_one
(mod->
mm
->
sm
->
config
,
"user.template.roster"
, 0);
253
if
(filename == NULL)
254
return
0;
255
256
tr = (
template_roster_t
) calloc(1,
sizeof
(
struct
_template_roster_st
));
257
258
tr->
sm
= mod->
mm
->
sm
;
259
tr->
filename
= filename;
260
261
mod->
private
= tr;
262
263
mod->
user_create
=
_template_roster_user_create
;
264
mod->
free
=
_template_roster_free
;
265
266
return
0;
267
}
Generated by
1.8.1.1