1package Asterisk::Conf;
2
3require 5.004;
4
5use Asterisk;
6
7$VERSION = '0.01';
8
9$MULTISEP = ',';
10
11sub version { $VERSION; }
12
13sub new {
14	my ($class, %args) = @_;
15	my $self = {};
16	$self->{configfile} = undef;
17	$self->{config} = {};
18	$self->{commit} = 0;
19	$self->{'contextorder'} = ();
20
21	$self->{'variables'} = {};
22
23	bless $self, ref $class || $class;
24	return $self;
25}
26
27sub DESTROY { }
28
29sub configfile {
30	my($self, $configfile) = @_;
31
32	if (defined($configfile)) {
33		$self->{'configfile'} = $configfile;
34	}
35
36	return $self->{'configfile'};
37}
38
39sub _setvar {
40	my ($self, $context, $var, $val, $order, $precomment, $postcomment) = @_;
41
42	if (defined($self->{config}{$context}{$var}{val}) && ($self->{'variables'}{$var}{type} =~ /^multi/)) {
43		$self->{config}{$context}{$var}{val} .= $MULTISEP . $val;
44	} else {
45		$self->{config}{$context}{$var}{val} = $val;
46		$self->{config}{$context}{$var}{precomment} = $precomment;
47		$self->{config}{$context}{$var}{postcomment} = $postcomment;
48		$self->{config}{$context}{$var}{order} = $order;
49	}
50
51}
52
53sub _addcontext {
54	my ($self, $context, $order) = @_;
55
56	if (!defined($order)) {
57		$order = ($#{$self->{contextorder}} + 1);
58	}
59	$self->{contextorder}[$order] = $context;
60}
61
62sub _contextorder {
63	my ($self) = @_;
64
65	return @{$self->{contextorder}};
66}
67
68sub readconfig {
69	my ($self) = @_;
70
71	my $context = '';
72	my $line = '';
73	my $precomment = '';
74	my $postcomment = '';
75
76	my $configfile = $self->configfile();
77	my $order = 0;
78	my $contextorder =0;
79
80	open(CF,"<$configfile") || die "Error loading $configfile: $!\n";
81	while ($line = <CF>) {
82#		chop($line);
83
84		if ($line =~ /^;/) {
85			$precomment .= $line;
86			next;
87		} elsif ($line =~ /(;.*)$/) {
88			$postcomment .= $1;
89			$line =~ s/;.*$//;
90		} elsif ($line =~ /^\s*$/) {
91			$precomment = '';
92			$postcomment = '';
93			next;
94		}
95
96		chop($line);
97		$line =~ s/\s*$//;
98
99		if ($line =~ /^\[(\w+)\]$/) {
100			$context = $1;
101			$self->_addcontext($context, $contextorder);
102			$contextorder++;
103		} elsif ($line =~ /^(\w+)\s*[=>]+\s*(.*)/) {
104			$self->_setvar($context, $1, $2, $order, $precomment, $postcomment);
105			$precomment = '';
106			$postcomment = '';
107			$order++;
108		} else {
109			print STDERR "Unknown line: $line\n" if ($DEBUG);
110		}
111	}
112	close(CF);
113	return %config;
114}
115
116sub rewriteconfig {
117	my ($self) = @_;
118	my $file = $self->{'configfile'};
119
120	my $fh;
121	open($fh, ">$file") || print "<br>OPEN FILE ERROR ($file) $!\n";
122	$self->writeconfig($fh);
123	close($fh);
124
125}
126
127
128sub writeconfig {
129	my ($self, $fh) = @_;
130
131	if (!$fh) {
132		$fh = \*STDERR;
133	}
134
135	foreach $context ($self->_contextorder) {
136		next if (!defined($self->{config}{$context}));
137		print $fh "[$context]\n";
138		foreach $key (keys %{$self->{config}{$context}}) {
139			next if (!$self->{config}{$context}{$key}{val});
140			print $fh $self->{config}{$context}{$key}{precomment};
141			my $val = $self->{config}{$context}{$key}{val};
142			if ($self->{'variables'}{$key}{type} =~ /^multi/) {
143				foreach (split(/$MULTISEP/, $val)) {
144					print $fh "$key => $_\n";
145				}
146			} else {
147				print $fh "$key => " . $val . "\n";
148			}
149		}
150		print $fh "\n";
151	}
152}
153
154sub setvariable {
155        my ($self, $context, $var, $val) = @_;
156
157        $self->{config}{$context}{$var}{val} = $val;
158        $self->{config}{$context}{$var}{postcomment} = ";Modified by Asterisk::Config::$self->{'name'}\n";
159
160}
161
162sub variablecheck {
163        my ($self, $context, $variable, $value) = @_;
164
165        my $ret = 0;
166	my $regex = $self->{'variables'}{$variables}{'regex'};
167
168        if (my $type = $self->{'variables'}{$variable}{'type'}) {
169		if ($type =~ /^multitext$/) {
170			foreach $multiv (split($MULTISEP, $value)) {
171				if ($multiv =~ /$regex/) {
172					$ret = 1;
173				}
174			}
175		} elsif ($type =~ /text$/) {
176                        if ($value =~ /$regex/) {
177                                $ret = 1;
178                        }
179                } elsif ($type eq 'one') {
180                        foreach $item (@{$self->{'variables'}{$variable}{'values'}}) {
181                                if ($item eq $value) {
182                                        $ret = 1;
183                                }
184                        }
185                }
186        }
187
188        return $ret;
189}
190
191sub cgiform {
192	my ($self, $action, $context, %vars) = @_;
193#valid actions: show, list, add, addform, modify, modifyform, delete, deleteform
194	my $html = '';
195
196	my $module = $self->{'name'};
197	my $URL = $ENV{'SCRIPT_NAME'};
198
199	$html .= "<!-- cgiform begin -->\n";
200
201	if (!$action) {
202		$action = 'list';
203	}
204
205	if (!$context && $action ne 'list') {
206		$html .= "<p>Context must be specified\n";
207		return $html;
208	}
209
210
211#if this is an addform we need to ask for the contextname
212	if ($action =~ /(.*)form$/) {
213                $html .= "<form method=\"post\">\n";
214		$html .= "<input type=\"hidden\" name=\"module\" value=\"$module\">\n";
215                $html .= "<input type=\"hidden\" name=\"context\" value=\"$context\">\n";
216                $html .= "<input type=\"hidden\" name=\"action\" value=\"$1\">\n";
217	}
218
219	if ($action eq 'list') {
220		foreach $context (@{$self->{'contextorder'}}) {
221			$html .= "<a href=\"$URL?module=$module&action=show&context=$context\">Context $context</a>\n";
222		}
223	}
224
225	if ($action eq 'deleteform') {
226		$html .= "<br>Are you sure you want to delete context $context?\n";
227		$html .= "<br><a href=\"$URL?module=$module&action=delete&context=$context&doit=1\">Confirm</a>\n";
228	} elsif ($action eq 'delete') {
229		if ($vars{'doit'} == 1 && $self->deletecontext($context)) {
230			$html .= "<br>Context $context has been deleted\n";
231			$self->{'commit'} = 1;
232		} else {
233			$html .= "<br>Unable to delete context $context\n";
234		}
235	} elsif ($action eq 'show' || $action =~ /^modify/ || $action =~ /^add/ ) {
236
237		if ($action eq 'add') {
238			$self->_addcontext($context);
239			$self->{'commit'} = 1;
240		} elsif ($action eq 'show') {
241			$html .= "<a href=\"$URL?module=$module&action=addform\">Add new</a>\n";
242			$html .= "<a href=\"$URL?module=$module&action=modifyform&context=$context\">Modify</a>\n";
243			$html .= "<a href=\"$URL?module=$module&action=deleteform&context=$context\">Delete</a>\n";
244		}
245		foreach $var ( sort keys %{$self->{'variables'}} ) {
246			my $value = '';
247
248#the logic here seems backwards, but trust me its right
249			if (my $regex = $self->{'variables'}{$var}{'contextregex'}) {
250				if ($context !~ /$regex/) {
251					next;
252				}
253			}
254			if (my $regex = $self->{'variables'}{$var}{'negcontextregex'}) {
255				if ($context =~ /$regex/) {
256					next;
257				}
258			}
259
260			if ($self->{'config'}{$context}{$var}{'val'}) {
261				$value = $self->{'config'}{$context}{$var}{'val'};
262			} else {
263				$value = $self->{'variables'}{$var}{'default'};
264			}
265
266			if ($action eq 'show') {
267				$html .= "<br>$var: $value\n";
268			} elsif ($action =~ /(.*)form$/) {
269				my $subaction = $1;
270				my $fieldtype = $self->{'variables'}{$var}{'type'};
271				$html .= "<input type=\"hidden\" name=\"OLD$var\" value=\"$value\">\n";
272				if ($fieldtype =~ /text$/) {
273					$html .= "<br>$var: <input type=\"text\" name=\"VAR$var\" value=\"$value\">\n";
274                                } elsif ($fieldtype eq 'one') {
275                                        $html .= "<br>$var: \n";
276                                        foreach $item (@{$self->{'variables'}{$var}{'values'}}) {
277                                                my $checked = 'checked' if ($item eq $value);
278                                                $html .= "<input type=\"radio\" name=\"VAR$var\" value=\"$item\" $checked> $item\n";
279                                        }
280                                }
281
282                        } elsif ($action eq 'modify' || $action eq 'add') {
283                                if ($action eq 'add' || ($vars{"VAR$var"} ne $vars{"OLD$var"})) {
284                                        my $newval = $vars{"VAR$var"};
285#need to check for valid value here
286	$html .= "<!-- Variable has changed $var = $newval -->\n";
287                                        if ($self->variablecheck($context, $var, $newval)) {
288$html .= "<br>SET VARIABLE $context $var=$newval\n";
289                                                $self->setvariable($context, $var, $newval);
290						$self->{'commit'} = 1;
291                                        }
292                                }
293
294                        }
295
296
297
298
299                }
300
301        }
302
303        if ($action =~ /form$/) {
304		$html .= "<br><input type=\nsubmit\n name=\"submit\">\n";
305                $html .= "</form>\n";
306        }
307
308	if ($self->{'commit'}) {
309print "<br>Going to try to commit\n";
310		$self->rewriteconfig();
311	}
312	$html .= "<!-- cgiform end -->\n";
313
314	return $html;
315}
316
317sub htmlheader {
318	my ($self, $title) = @_;
319	$title = $self->{'description'} if (!defined($title));
320	my $html = "<HTML><HEAD><TITLE>$title</TITLE></HEAD>\n";
321	$html .= "<BODY>\n";
322	return $html;
323}
324
325sub htmlfooter {
326	my ($self) = @_;
327	my $html = "</BODY></HTML>\n";
328	return $html;
329}
330
331sub deletecontext {
332	my ($self, $context) = @_;
333
334	if (delete($self->{'config'}{$context})) {
335		return 1;
336	} else {
337		return 0;
338	}
339}
340
341sub helptext {
342	my ($self, $helpname) = @_;
343
344}
345
3461;
347
348