Handle hostnames with upper-case letters
[webmin.git] / jabber / jabber-lib.pl
1 # jabber-lib.pl
2 # Common functions for editing the jabber config files
3 #
4 # XXX - http://prdownloads.sourceforge.net/expat/expat-1.95.2-1.i686.rpm
5 #     - XML::Parser  XML::Generator
6 # XXX - admin <read> and <write> - what do they mean?
7
8 BEGIN { push(@INC, ".."); };
9 use WebminCore;
10 &init_config();
11
12 if ($config{'jabber_lib'}) {
13         $ENV{$gconfig{'ld_env'}} .= ':' if ($ENV{$gconfig{'ld_env'}});
14         $ENV{$gconfig{'ld_env'}} .= $config{'jabber_lib'};
15         }
16
17 eval "use XML::Parser; \$got_xml_parser++";
18 eval "use XML::Generator; \$got_xml_generator++";
19
20 # get_jabber_config()
21 # Parse the jabber XML config file
22 sub get_jabber_config
23 {
24 return $get_jabber_config_cache if (defined($get_jabber_config_cache));
25 local $xml = new XML::Parser('Style' => 'Tree');
26 eval { $get_jabber_config_cache = $xml->parsefile($config{'jabber_config'}); };
27 if ($@) {
28         return $@;
29         }
30 return $get_jabber_config_cache;
31 }
32
33 # find(name, &config)
34 sub find
35 {
36 local (@rv, $i);
37 local $list = $_[1]->[1];
38 for($i=1; $i<@$list; $i+=2) {
39         if (lc($list->[$i]) eq lc($_[0])) {
40                 push(@rv, [ $list->[$i], $list->[$i+1], $i ]);
41                 }
42         }
43 return wantarray ? @rv : $rv[0];
44 }
45
46 # find_value(name, &config)
47 sub find_value
48 {
49 local @rv = map { &value_in($_) } &find($_[0], $_[1]);
50 return wantarray ? @rv : $rv[0];
51 }
52
53 # jabber_pid_file()
54 # Returns the PID file used by jabber
55 sub jabber_pid_file
56 {
57 local $conf = &get_jabber_config();
58 local $pidfile = &find_value("pidfile", $conf);
59 if ($pidfile =~ /^\//) {
60         return $pidfile;
61         }
62 elsif ($pidfile) {
63         return "$config{'jabber_dir'}/$pidfile";
64         }
65 else {
66         return "$config{'jabber_dir'}/jabber.pid";
67         }
68 }
69
70 # value_in(&tag)
71 sub value_in
72 {
73 return undef if (!$_[0]);
74 local $zero = &find("0", $_[0]);
75 return $zero ? $zero->[1] : undef;
76 }
77
78 # generate_config(&tree, &gen)
79 # Returns an XML::Generator object created from a config tree structure
80 sub generate_config
81 {
82 local $gen = $_[1] ? $_[1] : XML::Generator->new(escape => 'always');
83 local $list = $_[0]->[1];
84 local (@mems, $i);
85 for($i=1; $i<@$list-1; $i+=2) {
86         if ($list->[$i] eq '0') {
87                 push(@mems, $list->[$i+1]);
88                 }
89         else {
90                 push(@mems, &generate_config(
91                                 [ $list->[$i], $list->[$i+1] ], $gen));
92                 }
93         }
94 local $name = $_[0]->[0];
95 return $gen->$name($list->[0], @mems);
96 }
97
98 # save_jabber_config(&config)
99 sub save_jabber_config
100 {
101 &open_tempfile(CONFIG, ">$config{'jabber_config'}");
102 local $xml = &generate_config($_[0]);
103 &print_tempfile(CONFIG, $xml);
104 &print_tempfile(CONFIG, "\n");
105 &close_tempfile(CONFIG);
106 }
107
108 # save_directive(&config, name|&old, &new)
109 # Replaces all directives of some name with new values
110 sub save_directive
111 {
112 local @ov = ref($_[1]) ? @{$_[1]} : &find($_[1], $_[0]);
113 local @nv = @{$_[2]};
114 local ($i, $j);
115 for($i=0; $i<@ov || $i<@nv; $i++) {
116         local $idx = $ov[$i]->[2] if ($ov[$i]);
117         if ($ov[$i] && $nv[$i]) {
118                 # Updating an existing value
119                 $_[0]->[1]->[$idx] = $nv[$i]->[0];
120                 $_[0]->[1]->[$idx+1] = $nv[$i]->[1];
121                 }
122         elsif ($ov[$i]) {
123                 # Deleting an old value
124                 splice(@{$_[0]->[1]}, $idx, 2);
125                 map { $_->[2] -= 2 if ($_->[2] >= $idx) } @ov;
126                 }
127         else {
128                 # Adding a new value after the last non-text one
129                 local $nt = -1;
130                 for($j=1; $j<@{$_[0]->[1]}; $j+=2) {
131                         $nt = $j if ($_[0]->[1]->[$j] ne '0');
132                         }
133                 splice(@{$_[0]->[1]}, $nt+2, 0, $nv[$i]->[0], $nv[$i]->[1]);
134                 }
135         }
136 }
137
138 # find_by_tag(name, tag, value, &config)
139 sub find_by_tag
140 {
141 local @m = &find($_[0], $_[3]);
142 @m = grep { lc($_->[1]->[0]->{lc($_[1])}) eq lc($_[2]) } @m;
143 return wantarray ? @m : $m[0];
144 }
145
146 # xml_string(name, &tree, ...)
147 # Converts a list of XML structures into text
148 sub xml_string
149 {
150 local $rv = "";
151 for($i=0; $i<@_; $i+=2) {
152         local $xml = &generate_config([ $_[$i], $_[$i+1] ]);
153         if ($xml =~ /\S/) {
154                 $rv .= $xml."\n";
155                 }
156         }
157 return $rv;
158 }
159
160 # get_jabberd_version(&out)
161 sub get_jabberd_version
162 {
163 local $jabberd = $config{'jabber_daemon'} ? $config{'jabber_daemon'}
164                                     : "$config{'jabber_dir'}/bin/jabberd";
165 local $out = `$jabberd -v 2>&1`;
166 ${$_[0]} = $out;
167 return $out =~ /\s(1\.4\S*)/ ? $1 : undef;
168 }
169
170 # stop_jabber()
171 # Stops jabber, and returns undef on success or an error message on failure
172 sub stop_jabber
173 {
174 if ($config{'stop_cmd'}) {
175         &system_logged("$config{'stop_cmd'} </dev/null >/dev/null 2>&1");
176         }
177 else {
178         local $pid = &check_pid_file(&jabber_pid_file());
179         if ($pid) {
180                 &kill_logged('TERM', $pid) || return $!;
181                 }
182         else {
183                 return $text{'stop_epid'};
184                 }
185         }
186 unlink(&jabber_pid_file());
187 return undef;
188 }
189
190 # start_jabber()
191 # Starts jabber, and returns undef on success or an error message on failure
192 sub start_jabber
193 {
194 &system_logged("$config{'start_cmd'} </dev/null >/tmp/err 2>&1");
195 return undef;
196 }
197
198 @register_fields = ( 'name', 'email' );
199
200 @karma_presets = ( { 'heartbeat' => 2,  'init' => 10,
201                      'max' => 10,       'inc' => 1,
202                      'dec' => 1,        'penalty' => -6,
203                      'restore' => 10 },
204                    { 'heartbeat' => 2,  'init' => 50,
205                      'max' => 50,       'inc' => 4,
206                      'dec' => 1,        'penalty' => -5,
207                      'restore' => 50 },
208                    { 'heartbeat' => 2,  'init' => 64,
209                      'max' => 64,       'inc' => 6,
210                      'dec' => 1,        'penalty' => -3,
211                      'restore' => 64 }
212                   );
213
214 @filter_conds = ( "ns", "unavailable", "from", "resource", "subject", "body",
215                   "show", "type", "roster", "group" );
216
217 @filter_acts =  ( "error", "offline", "forward", "reply", "continue",
218                   "settype" );
219
220 1;
221