File Coverage

blib/lib/Unix/Conf/Bind8/Conf/Logging/Channel.pm
Criterion Covered Total %
statement 18 179 10.0
branch 0 142 0.0
condition 0 11 0.0
subroutine 6 24 25.0
pod 11 12 91.6
total 35 368 9.5


line stmt bran cond sub pod time code
1             # Logging::Channel
2             #
3             # Copyright Karthik Krishnamurthy
4              
5             =head1 NAME
6              
7             Unix::Conf::Bind8::Conf::Logging::Channel - Class implementing the channel
8             subdirective of the logging directive
9              
10             =head1 SYNOPSIS
11              
12             use Unix::Conf::Bind8;
13             my ($conf, $channel, $ret);
14              
15             $conf = Unix::Conf::Bind8->new_conf (
16             FILE => '/etc/named.conf',
17             SECURE_OPEN => 1,
18             ) or $conf->die ("couldn't open `named.conf'");
19              
20             # get an existing logging object
21             $channel = $conf->get_logging ()->get_channel ('some_channel')
22             or $channel->die ("couldn't get channel `some_channel'");
23              
24             # assuming previous output was syslog change output to file
25             # and set severity to debug at level 3
26             $ret = $channel->output ('file')
27             or $ret->die ("couldn't set output to `file'");
28             $ret = $channel->file ('my.log')
29             or $ret->die ("couldn't set file to `my.log'");
30             $ret = $channel->severity ( { NAME => 'debug', LEVEL => 3 } )
31             or $ret->die ("couldn't set severity");
32              
33             # also enable print-severity
34             $ret = $channel->print_severity ('yes')
35             or $ret->die ("couldn't enable `print-severity'");
36              
37             # and delete the `print-category' channel directive
38             # not delete is not the same as disabling by setting
39             # print-severity to no
40             $ret = $channel->delete_print_severity ()
41             or $ret->die ("couldn't delete `print-severity'");
42              
43             =head1 DESCRIPTION
44              
45             =over 4
46              
47             =cut
48              
49             package Unix::Conf::Bind8::Conf::Logging::Channel;
50              
51 10     10   45 use strict;
  10         18  
  10         416  
52 10     10   45 use warnings;
  10         18  
  10         230  
53 10     10   44 use Unix::Conf;
  10         13  
  10         177  
54              
55 10     10   43 use Unix::Conf::Bind8::Conf;
  10         20  
  10         351  
56 10     10   49 use Unix::Conf::Bind8::Conf::Lib;
  10         16  
  10         20479  
57              
58             =item new ()
59              
60             Arguments
61             PARENT => ref to a Unix::Conf::Bind8::Conf::Logging object
62             NAME => 'channel-name',
63             OUTPUT => 'value', # syslog|file|null
64             FILE => {
65             PATH => 'file-name', # only if OUTPUT eq 'file'
66             VERSIONS => value, # 'unlimited' | NUMBER
67             SIZE => value, # 'unlimited' | 'default' | NUMBER
68             }
69             SYSLOG => 'facility-name',# only if OUTPUT eq 'syslog'
70             SEVERITY => 'severity-name',
71             'PRINT-TIME' => 'value', # yes|no
72             'PRINT-SEVERITY' => 'value', # yes|no
73             'PRINT-CATEGORY' => 'value', # yes|no
74              
75             Class constructor
76             Creates a new Unix::Conf::Bind8::Logging::Channel object, initializes it
77             and returns it on success, or an Err object on failure.
78              
79             =cut
80              
81             sub new
82             {
83 0     0 1   my $self = shift ();
84 0           my %args = @_;
85 0           my $new = bless ({ DIRTY => 0 });
86 0           my $ret;
87            
88 0 0         return (Unix::Conf->_err ('new', "PARENT not specified"))
89             unless ($args{PARENT});
90 0 0         $ret = $new->_parent ($args{PARENT}) or return ($ret);
91 0 0         return (Unix::Conf->_err ('new', "channel name not specified"))
92             unless ($args{NAME});
93 0 0         $ret = $new->name ($args{NAME}) or return ($ret);
94              
95 0 0         if ($args{OUTPUT}) {
96 0 0         $ret = $new->output ($args{OUTPUT}) or return ($ret);
97              
98 0 0         if ($args{OUTPUT} eq 'file') {
    0          
99 0 0         return (Unix::Conf->_err ('output', "no arguments set for channel output 'file'"))
100             unless ($args{FILE});
101 0 0         $ret = $new->file (%{$args{FILE}}) or return ($ret);
  0            
102             }
103             elsif ($args{OUTPUT} eq 'syslog') {
104 0 0         return (Unix::Conf->_err ('output', "facility not specified for channel output `syslog'"))
105             unless ($args{SYSLOG});
106 0           $new->syslog ($args{SYSLOG});
107             }
108             }
109              
110 0 0 0       $ret = $new->severity (%{$args{SEVERITY}}) or return ($ret)
  0            
111             if ($args{SEVERITY});
112 0 0 0       $ret = $new->print_category ($args{'PRINT-CATEGORY'}) or return ($ret)
113             if ($args{'PRINT-CATEGORY'});
114 0 0 0       $ret = $new->print_severity ($args{'PRINT-SEVERITY'}) or return ($ret)
115             if ($args{'PRINT-SEVERITY'});
116 0 0 0       $ret = $new->print_time ($args{'PRINT-TIME'}) or return ($ret)
117             if ($args{'PRINT-TIME'});
118 0           return ($new);
119             }
120              
121             =item delete ()
122              
123             Arguments
124              
125             Object method.
126             Deletes the invocant.
127             Returns true on success, an Err object otherwise.
128              
129             =cut
130              
131             sub delete
132             {
133 0     0 1   my $self = $_[0];
134 0           my $ret;
135              
136 0           return (Unix::Conf->_err ("delete", "channel still in use, cannot delete"))
137 0 0         if (keys (%{$self->{categories}}));
138              
139 0 0         $ret = Unix::Conf::Bind8::Conf::Logging::_del_channel ($self->_parent (), $self->name ())
140             or return ($ret);
141 0           $self->__dirty (1);
142 0           return (1);
143             }
144              
145             =item name ()
146              
147             Arguments
148             'CHANNEL-NAME',
149              
150             Object method
151             Get/Set name attribute for the invoking object.
152             If called with an argument, sets channel name and returns true
153             on success, an Err object otherwise. Returns channel name if
154             invoked without an argument.
155              
156             =cut
157              
158             sub name
159             {
160 0     0 1   my ($self, $name) = @_;
161              
162 0 0         if (defined ($name)) {
163 0           my $ret;
164 0 0         return (UNix::Conf->_err ('name', "illegal channel name `$name'"))
165             unless ($name);
166 0 0         return (Unix::Conf->_err ('name', "channel `$name' is predefined"))
167             if (Unix::Conf::Bind8::Conf::Logging::_is_predef_channel ($name));
168 0 0         if ($self->{name}) {
169 0 0         $ret = Unix::Conf::Bind8::Conf::Logging::_del_channel ($self)
170             or return ($ret);
171             }
172 0           $self->{name} = $name;
173 0 0         $ret = Unix::Conf::Bind8::Conf::Logging::_add_channel ($self)
174             or return ($ret);
175 0           $self->__dirty (1);
176 0           return (1);
177             }
178             return (
179 0 0         $self->{name} ? $self->{name} :
180             Unix::Conf->_err ('name', "channel `$name' not defined")
181             );
182             }
183              
184             =item output ()
185              
186             Arguments
187             'OUTPUT', # syslog|file|null
188              
189             Object method.
190             Get/set attributes for the invoking object.
191             If called with an argument, tries to set the output to argument and
192             returns true if successful, an Err object otherwise. Returns the
193             currently set output if set, an Err object otherwise if called without
194             an argument.
195              
196             =cut
197              
198             sub output
199             {
200 0     0 1   my ($self, $output) = @_;
201              
202 0 0         if ($output) {
203 0 0         return (Unix::Conf->_err ('output', "illegal channel output `$output'"))
204             if ($output !~ /^(syslog|file|null)$/);
205 0           $self->{output} = $output;
206 0           $self->__dirty (1);
207 0           return (1);
208             }
209             return (
210 0 0         $self->{output} ? $self->{output} :
211             Unix::Conf->_err ('output', "channel output not defined")
212             );
213             }
214              
215             =item file ()
216              
217             Arguments
218             PATH => 'path_name',
219             VERSIONS => versions_allowed, # 'unlimited' | NUMBER
220             SIZE => size_spec, # 'unlimited' | 'default' | NUMBER
221              
222             Object method.
223             Get/set file attributes for the invoking object.
224             If argument is passed, the method tries to set the file parameters and
225             returns true if successful, an Err object otherwise. Returns a hash ref
226             containing information in the same format as the argument, if defined,
227             an Err object otherwise, if called without an argument.
228              
229             =cut
230              
231             sub file
232             {
233 0     0 1   my $self = shift ();
234 0           my %args = @_;
235              
236 0 0         if ($args{PATH}) {
237 0           $self->{path} = $args{PATH};
238 0           __valid_string ($self->{path});
239 0 0         if (defined ($args{VERSIONS})) {
240 0 0         return (Unix::Conf->_err ('file', "illegal versions argument `$args{VERSIONS}'"))
241             if ($args{VERSIONS} !~ /^(\d+|unlimited)$/);
242 0           $self->{versions} = $args{VERSIONS};
243             }
244 0 0         if (defined ($args{SIZE})) {
245 0 0         return (Unix::Conf->_err ('file', "illegal size argument `$args{SIZE}'"))
246             unless (__valid_sizespec ($args{SIZE}));
247 0           $self->{size} = $args{SIZE};
248             }
249 0           $self->__dirty (1);
250 0           return (1);
251             }
252 0 0         return (Unix::Conf->_err ('file', "file path not defined"))
253             unless ($self->{path});
254 0           return ({ PATH => $self->{path}, VERSIONS => $self->{versions}, SIZE => $self->{size} });
255             }
256              
257             =item syslog ()
258              
259             Arguments
260             facility, # kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron
261             # |authpriv|ftp|local0|local1|local2|local3|local4|local5
262             # local6|local7
263             Object method.
264             Get/Set the syslog attribute of the invoking channel object.
265             If called with an argument, the method tries to set the facility and
266             returns true if successful, an Err object otherwise. Returns defined
267             facility if called without an argument, an Err object otherwise.
268              
269             =cut
270              
271             sub syslog
272             {
273 0     0 1   my ($self, $syslog) = @_;
274              
275 0 0         if ($syslog) {
276 0 0         return (Unix::Conf->_err ('syslog', "illegal syslog facility"))
277             if ($syslog !~ /^(kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|authpriv|ftp|local[0-7])$/);
278 0           $self->{syslog} = $syslog;
279 0           $self->__dirty (1);
280 0           return (1);
281             }
282             return (
283 0 0         $self->{syslog} ? $self->{syslog} : Unix::Conf->_err ('syslog', "syslog facility not defined")
284             );
285             }
286              
287             =item severity ()
288              
289             Arguments
290             NAME => severity, # critical|error|warning|notice|info
291             # |debug|dynamic
292             LEVEL => number, # debug level. to be specified only if
293             # severity is debug.
294              
295             Object method
296             Get/Set the severity attribute of the invoking object.
297             If argument is specified the method tries to set the severity and
298             returns true on success, an Err object on failure. Returns defined
299             severity if called without an argument, an Err object otherwise.
300              
301             =cut
302              
303             sub severity
304             {
305 0     0 1   my $self = shift ();
306 0           my %args = @_;
307              
308 0 0         if ($args{NAME}) {
309 0 0         return (Unix::Conf->_err ('severity', "illegal severity `$args{NAME}'"))
310             if ($args{NAME} !~ /^(critical|error|warning|notice|info|debug|dynamic)$/);
311 0 0 0       return (Unix::Conf->_err ('severity', "LEVEL can be set only for severity `debug'"))
312             if ($args{LEVEL} && $args{NAME} ne 'debug');
313 0           $self->{severity} = $args{NAME};
314 0           $self->{level} = $args{LEVEL};
315 0           $self->__dirty (1);
316 0           return (1);
317             }
318 0 0         return (Unix::Conf->_err ('severity', "severity not defined"))
319             unless ($self->{severity});
320 0           return (return ({ NAME => $self->{severity}, LEVEL => $self->{level}}));
321             }
322              
323             =item print_time ()
324              
325             Arguments
326             yes_no,
327              
328             Object method.
329             Get/Set attribute of the invoking Channel object.
330             If argument is passed, this method tries to set the value and returns
331             true on success, an Err object on failure. Returns defined value of
332             'print-time' if defined, an Err object otherwise, if called without an
333             argument.
334              
335             =cut
336              
337             sub print_time
338             {
339 0     0 1   my ($self, $print) = @_;
340              
341 0 0         if ($print) {
342 0 0         return (Unix::Conf->_err ('print_time', "illegal argument `$print'"))
343             unless (__valid_yesno ($print));
344 0           $self->{'print-time'} = $print;
345 0           $self->__dirty (1);
346 0           return (1);
347             }
348             return (
349 0 0         $self->{'print-time'} ? $self->{'print-time'} :
350             Unix::Conf->_err ('print_time', "print-time not defined")
351             );
352             }
353              
354             =item print_category ()
355              
356             Arguments
357             yes_no,
358              
359             Object method.
360             Get/Set attribute of the invoking Channel object.
361             If argument is passed, this method tries to set the value and returns
362             true on success, an Err object on failure. Returns defined value of
363             'print-category' if defined, an Err object otherwise, if called without
364             an argument.
365              
366             =cut
367              
368             sub print_category
369             {
370 0     0 1   my ($self, $print) = @_;
371              
372 0 0         if ($print) {
373 0 0         return (Unix::Conf->_err ('print_category', "illegal argument `$print'"))
374             unless (__valid_yesno ($print));
375 0           $self->{'print-category'} = $print;
376 0           $self->__dirty (1);
377 0           return (1);
378             }
379             return (
380 0 0         $self->{'print-category'} ? $self->{'print-category'} :
381             Unix::Conf->_err ('print_category', "print-category not defined")
382             );
383             }
384              
385             =item print_severity ()
386              
387             Arguments
388             yes_no,
389              
390             Object method.
391             Get/Set attribute of the invoking Channel object.
392             If argument is passed, this method tries to set the value and returns
393             true on success, an Err object on failure. Returns defined value of
394             'print-severity' if defined, an Err object otherwise, if called
395             without an argument.
396              
397             =cut
398              
399             sub print_severity
400             {
401 0     0 1   my ($self, $print) = @_;
402              
403 0 0         if ($print) {
404 0 0         return (Unix::Conf->_err ('print_severity', "illegal argument `$print'"))
405             unless (__valid_yesno ($print));
406 0           $self->{'print-severity'} = $print;
407 0           $self->__dirty (1);
408 0           return (1);
409             }
410             return (
411 0 0         $self->{'print-severity'} ? $self->{'print-severity'} :
412             Unix::Conf->_err ('print_severity', "print-severity not defined")
413             );
414             }
415              
416             my %Channel_Directives = (
417             'output' => 1,
418             'severity' => 1,
419             'print-category' => 1,
420             'print-severity' => 1,
421             'print-time' => 1,
422             );
423              
424             =cut delete_channeldir ()
425              
426             Arguments
427             'directive-name',
428              
429             Tries to delete the directive specified by argument if defined.
430             Returns true on success, an Err object otherwise.
431              
432             =cut
433              
434             sub delete_channeldir
435             {
436 0     0 0   my ($self, $directive) = @_;
437              
438 0 0         return (Unix::Conf->_err ('delete_channeldir', "illegal channel directive `$directive'"))
439             unless ($Channel_Directives{$directive});
440 0 0         return (Unix::Conf->_err ("delete_channeldir", "channel directive `$directive' not defined"))
441             unless ($self->{$directive});
442 0           undef ($self->{$directive});
443 0           $self->__dirty (1);
444 0           return (1);
445             }
446              
447             =item delete_output ()
448              
449             =item delete_severity ()
450              
451             =item delete_print_time ()
452              
453             =item delete_print_category ()
454              
455             =item delete_print_severity ()
456              
457             Deletes the relevant directives and returns true, if defined, an Err object
458             otherwise.
459              
460             =cut
461              
462             for my $directive (keys (%Channel_Directives)) {
463 10     10   72 no strict 'refs';
  10         19  
  10         8932  
464             my $meth = $directive;
465             $meth =~ s/-/_/g;
466             *{"delete_$meth"} = sub {
467 0     0     my $self = $_[0];
468 0 0         return (Unix::Conf->_err ("delete_$meth", "channel directive `$directive' not defined"))
469             unless ($self->{$directive});
470 0           undef ($self->{$directive});
471 0           $self->__dirty (1);
472 0           return (1);
473             };
474             }
475              
476             =item categories ()
477              
478             Object method.
479             Returns the categories that have defined this channel. In scalar context
480             returns the number of categories, returns a list of category names in list
481             context.
482              
483             =cut
484              
485             sub categories ()
486             {
487 0     0 1   return (keys (%{$_[0]->{categories}}));
  0            
488             }
489              
490             sub _add_category ()
491             {
492 0     0     my $self = shift ();
493              
494 0 0         return (Unix::Conf->_err ("_add_category", "categories to be added not passed"))
495             unless (@_);
496            
497 0           @{$self->{categories}}{@_} = (1) x @_;
  0            
498 0           return (1);
499             }
500              
501             sub _delete_category ()
502             {
503 0     0     my $self = shift ();
504              
505 0 0         return (Unix::Conf->_err ("_delete_category", "categories to be deleted not passed"))
506             unless (@_);
507              
508 0           for (@_) {
509             return (
510 0 0         Unix::Conf->_err (
511             "_delete_category",
512             sprintf ("category `$_' does not use %s", $self->name ())
513             )
514             ) unless ($self->{categories}{$_});
515             }
516 0           delete (@{$self->{categories}}{@_});
  0            
517 0           return (1);
518             }
519              
520             sub __render
521             {
522 0     0     my $self = $_[0];
523 0           my ($tmp, $rendered);
524              
525 0           $rendered = sprintf ("\tchannel %s {\n", $self->name ());
526 0 0         if (($tmp = $self->output ()) eq 'file') {
    0          
    0          
527 0           my $file;
528 0 0         $file = $self->file () or return ($file);
529 0           $rendered .= qq (\t\tfile "$file->{PATH}");
530 0 0         $rendered .= " versions $file->{VERSIONS}"
531             if ($file->{VERSIONS});
532 0 0         $rendered .= " size $file->{SIZE}"
533             if ($file->{SIZE});
534 0           $rendered .= ";\n";
535             }
536             elsif ($tmp eq 'syslog') {
537             # while the syntax in the man page indicates that
538             # a syslog facility is mandatory, the sample named.conf
539             # file that comes with named-8.2.3 has just such an
540             # example
541 0           my $facility;
542 0           $rendered .= "\t\tsyslog";
543 0 0         $rendered .= " $facility"
544             if (($facility = $self->syslog ()));
545 0           $rendered .= ";\n";
546             }
547             elsif ($tmp eq 'null') {
548 0           $rendered .= "\t\tnull;\n";
549             }
550              
551 0 0         if (($tmp = $self->severity ())) {
552 0           $rendered .= "\t\tseverity $tmp->{NAME}";
553 0 0         $rendered .= " $tmp->{LEVEL}"
554             if ($tmp->{LEVEL});
555 0           $rendered .= ";\n";
556             }
557 0 0         $rendered .= "\t\tprint-category $tmp;\n"
558             if (($tmp = $self->print_category ()));
559 0 0         $rendered .= "\t\tprint-severity $tmp;\n"
560             if (($tmp = $self->print_severity ()));
561 0 0         $rendered .= "\t\tprint-time $tmp;\n"
562             if (($tmp = $self->print_time ()));
563 0           $rendered .= "\t};\n";
564 0           return ($rendered);
565             }
566              
567             sub __dirty
568             {
569 0 0   0     if (defined ($_[1])) {
570 0           $_[0]->{PARENT}->dirty ($_[1]);
571 0           return (1);
572             }
573 0           return ($_[0]->{PARENT}->dirty ());
574             }
575              
576             # Stores the Logging object.
577             sub _parent
578             {
579 0     0     my ($self, $parent) = @_;
580              
581 0 0         if ($parent) {
582             # Do not allow resetting the PARENT ref. We don't use
583             # PARENT for anything else except calling the dirty method.
584 0 0         return (Unix::Conf->_err ('__parent', "PARENT already defined. Cannot reset"))
585             if ($self->{PARENT});
586 0           $self->{PARENT} = $parent;
587 0           return (1);
588             }
589             return (
590 0 0         $self->{PARENT} ? $self->{PARENT} :
591             Unix::Conf->_err ('_parent', "PARENT not defined")
592             );
593             }
594              
595             1;
596             __END__