File Coverage

blib/lib/BGPmon/Configure.pm
Criterion Covered Total %
statement 177 561 31.5
branch 0 174 0.0
condition 0 18 0.0
subroutine 59 78 75.6
pod 7 19 36.8
total 243 850 28.5


line stmt bran cond sub pod time code
1             package BGPmon::Configure;
2             our $VERSION = '2.0';
3              
4 1     1   62450 use 5.14.0;
  1         5  
  1         50  
5 1     1   6 use strict;
  1         1  
  1         40  
6 1     1   6 use warnings;
  1         6  
  1         254  
7 1     1   6 use Getopt::Long;
  1         2  
  1         6  
8              
9             require Exporter;
10             our %EXPORT_TAGS = ( "all" => [ qw(configure parameter_value
11             parameter_set_by set_parameter
12             get_error_code get_error_message
13             get_error_msg ) ] );
14             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
15             our @ISA = qw(Exporter);
16              
17             # --- The Name For The Configuration File Command Line Option ---
18             # The recommended command line option is -config_file, but you can change the
19             # option name to something else by setting the constant below
20 1     1   317 use constant CONFIG_FILE_PARAMETER_NAME => "config_file";
  1         3  
  1         77  
21              
22             # --- constants used to indicate who set a parameter ---
23 1     1   6 use constant NOT_SET => 0;
  1         2  
  1         46  
24 1     1   11 use constant DEFAULT => 1;
  1         2  
  1         48  
25 1     1   4 use constant COMMAND_LINE => 2;
  1         2  
  1         42  
26 1     1   8 use constant CONFIG_FILE => 3;
  1         2  
  1         48  
27 1     1   5 use constant SET_FUNCTION => 4;
  1         2  
  1         38  
28 1     1   5 use constant SET_ERROR => 5;
  1         2  
  1         94  
29             my @SETBY_VALUES = (NOT_SET, DEFAULT, COMMAND_LINE, CONFIG_FILE, SET_FUNCTION);
30              
31             # --- The Supported Parameter Types ---
32 1     1   5 use constant ADDRESS => 0;
  1         2  
  1         67  
33 1     1   6 use constant PORT => 1;
  1         3  
  1         53  
34 1     1   20 use constant FILE => 2;
  1         3  
  1         75  
35 1     1   7 use constant BOOLEAN => 3;
  1         1  
  1         55  
36 1     1   6 use constant STRING => 4;
  1         1  
  1         142  
37 1     1   6 use constant UNSIGNED_INT => 5;
  1         2  
  1         301  
38             my @SUPPORTED_TYPES = (ADDRESS, PORT, FILE, BOOLEAN, STRING, UNSIGNED_INT);
39              
40             # if you add a new parameter type, you must
41             # 1. define a name for the new type above
42             # 2. add the new type to @SUPPORTED_TYPES array above
43             # 3. add a string that will be displayed in the usage messag by setting
44             # $USAGE_MSG_FOR_TYPE{$YOUR_NEW_TYPE}
45             # 4 add a string that tells GetOpt what type of command line arguement is
46             # expected by setting GETOPT_PARAM_FOR_TYPE{$YOUR_NEW_TYPE}
47             # - modify set_parameter_by_value to handle error checking for you new type
48              
49             # usage messages for each type
50             my %USAGE_MSG_FOR_TYPE;
51             $USAGE_MSG_FOR_TYPE{ADDRESS()} = "IP_adddress";
52             $USAGE_MSG_FOR_TYPE{PORT()} = "port";
53             $USAGE_MSG_FOR_TYPE{FILE()} = "filename";
54             $USAGE_MSG_FOR_TYPE{BOOLEAN()} = "";
55             $USAGE_MSG_FOR_TYPE{STRING()} = "string";
56             $USAGE_MSG_FOR_TYPE{UNSIGNED_INT()} = "non_negative_number";
57              
58             # GetOpt paramater for each type
59             my %GETOPT_PARAM_FOR_TYPE;
60             $GETOPT_PARAM_FOR_TYPE{ADDRESS()} = "=s";
61             $GETOPT_PARAM_FOR_TYPE{PORT()} = "=i";
62             $GETOPT_PARAM_FOR_TYPE{FILE()} = "=s";
63             $GETOPT_PARAM_FOR_TYPE{BOOLEAN()} = "!";
64             $GETOPT_PARAM_FOR_TYPE{STRING()} = "=s";
65             $GETOPT_PARAM_FOR_TYPE{UNSIGNED_INT()} = "=i";
66            
67             # --- constants used to indicate error codes and messages---
68 1     1   6 use constant NO_ERROR_CODE => 0;
  1         2  
  1         1140  
69 1         52 use constant NO_ERROR_MSG =>
70 1     1   8 'No Error';
  1         2  
71 1     1   6 use constant NO_FUNCTION_SPECIFIED_CODE => 1;
  1         2  
  1         281  
72 1         102 use constant NO_FUNCTION_SPECIFIED_MSG =>
73 1     1   8 'Error reporting function called without specifying the function.';
  1         2  
74 1     1   7 use constant INVALID_FUNCTION_SPECIFIED_CODE => 2;
  1         2  
  1         60  
75 1         97 use constant INVALID_FUNCTION_SPECIFIED_MSG =>
76 1     1   6 'Error reporting function called with invalid function name';
  1         2  
77 1     1   7 use constant NO_PARAMETER_SPECIFIED_CODE => 3;
  1         2  
  1         53  
78 1         122 use constant NO_PARAMETER_SPECIFIED_MSG =>
79 1     1   5 'No parameter name specified';
  1         2  
80 1     1   14 use constant NOT_A_VALID_PARAMETER_CODE => 4;
  1         2  
  1         55  
81 1         47 use constant NOT_A_VALID_PARAMETER_MSG =>
82 1     1   5 'Invalid parameter name';
  1         2  
83 1     1   8 use constant NO_VALUE_ASSIGNED_CODE => 5;
  1         2  
  1         50  
84 1         58 use constant NO_VALUE_ASSIGNED_MSG =>
85 1     1   6 'No value has been assigned to this parameter';
  1         2  
86 1     1   5 use constant UNDEFINED_SETBY_CODE => 6;
  1         2  
  1         42  
87 1         58 use constant UNDEFINED_SETBY_MSG =>
88 1     1   5 'The SetBy field of the parameter is undefined';
  1         2  
89 1     1   7 use constant INVALID_SETBY_CODE => 7;
  1         2  
  1         51  
90 1         49 use constant INVALID_SETBY_MSG =>
91 1     1   5 'The SetBy field of the parameter is invalid.';
  1         2  
92 1     1   5 use constant INVALID_VALUE_CODE => 8;
  1         2  
  1         48  
93 1         41 use constant INVALID_VALUE_MSG =>
94 1     1   5 'Invalid value for parameter';
  1         20  
95 1     1   5 use constant PARAMETER_CREATION_ERROR_CODE => 9;
  1         154  
  1         59  
96 1         48 use constant PARAMETER_CREATION_ERROR_MSG =>
97 1     1   15 'Error creating the paramter - missing parameter hash';
  1         2  
98 1     1   44 use constant PARAMETER_CREATION_MISSING_NAME_CODE => 10;
  1         3  
  1         136  
99 1         50 use constant PARAMETER_CREATION_MISSING_NAME_MSG =>
100 1     1   6 'Error creating the paramter - parameter name is missing';
  1         1  
101 1     1   6 use constant PARAMETER_CREATION_MISSING_TYPE_CODE => 11;
  1         1  
  1         44  
102 1         41 use constant PARAMETER_CREATION_MISSING_TYPE_MSG =>
103 1     1   5 'Error creating the paramter - parameter name is missing';
  1         2  
104 1     1   5 use constant PARAMETER_CREATION_INVALID_TYPE_CODE => 12;
  1         2  
  1         48  
105 1         133 use constant PARAMETER_CREATION_INVALID_TYPE_MSG =>
106 1     1   5 'Error creating the paramter - invalid type ';
  1         3  
107 1     1   6 use constant PARAMETER_CREATION_INVALID_ELEMENT_CODE => 13;
  1         2  
  1         71  
108 1         53 use constant PARAMETER_CREATION_INVALID_ELEMENT_MSG =>
109 1     1   5 'Error creating the paramter - invalid element ';
  1         2  
110 1     1   5 use constant PARAMETER_CREATION_INVALID_DEFAULT_CODE => 14;
  1         2  
  1         97  
111 1         43 use constant PARAMETER_CREATION_INVALID_DEFAULT_MSG =>
112 1     1   5 'Error creating the paramter - invalid default value ';
  1         2  
113 1     1   6 use constant PARAMETER_CREATION_NO_H_OPT_CODE => 15;
  1         1  
  1         51  
114 1         46 use constant PARAMETER_CREATION_NO_H_OPT_MSG =>
115 1     1   5 'Error creating the paramter - parameter name -h and -help are reserved';
  1         2  
116 1     1   5 use constant PARAMETER_CREATION_INVALID_CONFIG_FILE_TYPE_CODE => 16;
  1         2  
  1         43  
117 1         45 use constant PARAMETER_CREATION_INVALID_CONFIG_FILE_TYPE_MSG =>
118 1     1   5 'Error creating the paramter - config file must be type FILE';
  1         1  
119 1     1   5 use constant COMMAND_LINE_USAGE_CONSTRUCTION_ERROR_CODE => 17;
  1         2  
  1         124  
120 1         56 use constant COMMAND_LINE_USAGE_CONSTRUCTION_ERROR_MSG =>
121 1     1   7 'Unable to construct usage message for command line';
  1         1  
122 1     1   5 use constant CONFIG_FILE_NOT_FOUND_CODE => 19;
  1         2  
  1         117  
123 1         42 use constant CONFIG_FILE_NOT_FOUND_MSG =>
124 1     1   6 'Configuration file not found';
  1         2  
125 1     1   5 use constant CONFIG_FILE_OPEN_FAILED_CODE => 20;
  1         2  
  1         50  
126 1         40 use constant CONFIG_FILE_OPEN_FAILED_MSG =>
127 1     1   5 'Failed to open configuration file';
  1         3  
128 1     1   5 use constant CONFIG_FILE_INVALID_LINE_CODE => 21;
  1         1  
  1         50  
129 1         5738 use constant CONFIG_FILE_INVALID_LINE_MSG =>
130 1     1   5 'Invalid line in configuration file: ';
  1         2  
131              
132             # --- error code/message ---
133             my %error_code;
134             my %error_msg;
135             # init the error codes for all functions
136             my @function_names = ("configure", "parameter_value",
137             "parameter_set_by", "set_parameter",
138             "set_parameter_to_value", "create_param",
139             "read_config", "read_file" );
140             for my $function_name (@function_names) {
141             $error_code{$function_name} = NO_ERROR_CODE;
142             $error_msg{$function_name} = NO_ERROR_MSG;
143             }
144              
145             # --- hash arrays for storing the parameters
146             my %Value; # current parameter value
147             my %Type; # parameter type (port, address, boolean, string, file)
148             my %Default; # the default value, command line/config_file overrides
149             my %Description; # description of the parameter for usage message.
150             my %SetBy; # indicates how the parameter was set.
151              
152             =head1 NAME
153              
154             BGPmon::Configure - BGPmon Client Configuration
155              
156             This module sets initial configuration variables from a combination of default
157             values, configuration file parameters, and command line options.
158              
159             =cut
160              
161             =head1 SYNOPSIS
162              
163             The module allows one to specify a set of configuration parameters and the
164             module sets these parameters based on a cominbation of default vaules,
165             command line options, and configuration file settings. The module does the
166             work of parsing the commmand line, generating any usage messages, and
167             reading a configuration file. You simply specify the input paramters you
168             would like to allow in the configuation file and on the commmand line.
169              
170             To specify a parameter, you must provide a parameter Name and parameter Type.
171             Possible Types are ADDRESS, PORT, FILE, BOOLEAN, STRING, and UNSIGNED_INT.
172              
173             Once you have specified the paramters, the configure function will take
174             care of generating command line arguements and will generate any usage errors
175             if the user does not specify correct command line options.
176              
177             You may optionally specify a Description and your description text will appear
178             after this option in any Usage message.
179              
180             The configure function will also read from a configuration file. Note that
181             values set by the command line take precedence and over-ride any settings
182             found in the configuration file. The user can specify the configuration file
183             with -c file or with -config_file file.
184              
185             You may also specify a Default configuration file or specify a Default for any
186             other option. Settings found in the configutaion file and command line take
187             precedence over any default settings.
188              
189             Once you have specified your parameters and called configure(%your_params),
190             you can use get_paramter("param_name") to get the value of any paramter.
191             You can also call parameter_set_by("param_name") to see if the parameter
192             was set using the default, the config file, or the command line
193             (or was not set at all).
194              
195             Finally, if you want to later over-ride any parameter, you can set it to
196             a value using set_parameter("param_name", value). This is not recommended.
197             You should rely on your defaults, the config file, and the command line
198             to set your parameters. But set_parameter is provided as option in case
199             special cases need it.
200              
201             Example:
202              
203             use BGPmon::Configure;
204             # lets define some parameters for my program
205             my @params = (
206             {
207             Name => BGPmon::Configure::CONFIG_FILE_PARAMETER_NAME,
208             Type => BGPmon::Configure::FILE,
209             Default => "./foo",
210             Description => "this is the configuration file name",
211             },
212             {
213             Name => "server",
214             Type => BGPmon::Configure::ADDRESS,
215             Default => "127.0.0.1",
216             Description => "this is the server address",
217             },
218             {
219             Name => "port",
220             Type => BGPmon::Configure::PORT,
221             Default => 50002,
222             Description => "this is the server port",
223             },
224             {
225             Name => "output_file",
226             Type => BGPmon::Configure::FILE,
227             Default => "/tmp/file",
228             Description => "My Output File",
229             },
230             {
231             Name => "use_syslog",
232             Type => BGPmon::Configure::BOOLEAN,
233             Description => "Use Syslog for error checking",
234             },
235             {
236             Name => "somestring",
237             Type => BGPmon::Configure::STRING,
238             Default => "This is a string used for something",
239             },
240             {
241             Name => "log_level",
242             Type => BGPmon::Configure::UNSIGNED_INT,
243             Default => 7,
244             }
245             );
246              
247             # now tell the module to set those parameters
248              
249             if (BGPmon::Configure::configure(@params) ) {
250             my $code = BGPmon::Configure::get_error_code("configure");
251             my $msg = BGPmon::Configure::get_error_message("configure");
252             print "Error Code is $code and message is $msg \n";
253             exit;
254             }
255              
256             # let's see what parameter "server" got set to
257              
258             my $srv = BGPmon::Configure::parameter_value("server");
259             if (defined($srv)) {
260             print "The server parameter was set to $srv\n";
261             }
262              
263             # let's see how parameter "server" was set
264              
265             my $setby = BGPmon::Configure::parameter_set_by("server");
266             if ($setby == BGPmon::Configure::NOT_SET) {
267             print "The server parameter has not been set\n";
268             } elsif ($setby == BGPmon::Configure::DEFAULT) {
269             print "The server parameter was set to the default value \n";
270             } elsif ($setby == BGPmon::Configure::COMMAND_LINE) {
271             print "The user set the server parameter from the command line\n";
272             } elsif ($setby == BGPmon::Configure::CONFIG_FILE) {
273             print "The server parameter was set in the configuration file\n";
274             } elsif ($setby == BGPmon::Configure::SET_ERROR) {
275             print "something went wrong... the parameter has an error\n";
276             }
277              
278             # this is not recommended, but we can over-ride that setting and
279             change the parameter value
280              
281             my $new_srv = "127.0.0.1";
282              
283             if (BGPmon::Configure::set_parameter("server", $new_srv) ) {
284             my $code = BGPmon::Configure::get_error_code("set_parameter");
285             my $msg = BGPmon::Configure::get_error_message("set_parameter");
286             print "Error Code is $code and message is $msg \n";
287             exit;
288             }
289              
290             if (BGPmon::Configure::parameter_set_by("server") ==
291             BGPmon::Configure::SET_FUNCTION ) {
292             print "I over-rode everything and set the server parameter to $new_srv\n";
293             }
294              
295             =head1 EXPORT
296              
297             configure
298             parameter_value
299             parameter_set_by
300             set_parameter
301              
302             =head1 SUBROUTINES/METHODS
303              
304             =head2 configure
305              
306             set initial configuration variables from a combination of default values,
307             configuration file parameters, and command line options
308              
309             Input : an array of hashes that specify the configuration parameters.
310             Each configuration parameter is represented by one hash with elements:
311             1. Name - (required) the name of the paramter
312             as it will appear in the command line and configuration file
313             2. Type - (required) the type of value associated with this name.
314             supported types include address, port, boolean, unsigned integer.
315             3. Default (optional) - the default value to associate with this
316             parameter if it is not found in the config file or command line
317             4. Description (optional) - A description to appear in a usage message
318              
319             Output: 0 on success, 1 on error and error code and error message are set
320             =cut
321             sub configure {
322 0     0 1   my @params = @_;
323            
324             # set function name for error reporting
325 0           my $function_name = $function_names[0];
326              
327             # run through all the parameters and set up the default values
328             # (if default is present)
329 0           for my $i ( 0 .. $#params ) {
330 0 0         if (create_param(($params[$i])) ) {
331 0           $error_code{$function_name} = $error_code{$function_names[4]};
332 0           $error_msg{$function_name} = $error_msg{$function_names[4]};
333 0           return 1;
334             }
335             }
336 0 0         if (read_command_line()) {
337 0           $error_code{$function_name} = $error_code{$function_names[5]};
338 0           $error_msg{$function_name} = $error_msg{$function_names[5]};
339 0           return 1;
340             }
341 0 0         if (read_config_file()) {
342 0           $error_code{$function_name} = $error_code{$function_names[6]};
343 0           $error_msg{$function_name} = $error_msg{$function_names[6]};
344 0           return 1;
345             }
346              
347 0           $error_code{$function_name} = NO_ERROR_CODE;
348 0           $error_msg{$function_name} = NO_ERROR_MSG;
349 0           return 0;
350             }
351              
352              
353             =head2 parameter_value
354              
355             Return the setting for a configuraion parameter
356              
357             Input : the name of the paramter
358              
359             Output: the value of the parameter.
360             if the input name does not correspond to a parameter,
361             the function returns undef and sets error code and error message
362             =cut
363             sub parameter_value {
364 0     0 1   my $name = shift;
365              
366             # set function name for error reporting
367 0           my $function_name = $function_names[1];
368              
369             # check we got a the name of some parameter
370 0 0         if (!defined($name)) {
371 0           $error_code{$function_name} = NO_PARAMETER_SPECIFIED_CODE;
372 0           $error_msg{$function_name} = NO_PARAMETER_SPECIFIED_MSG;
373 0           return undef;
374             }
375              
376             # check the name matches a parameter for this program
377             # note a parameter may or may not have an assigned value,
378             # but every valid parameter must have a type
379 0 0         if (!defined($Type{$name}) ) {
380 0           $error_code{$function_name} = NOT_A_VALID_PARAMETER_CODE;
381 0           $error_msg{$function_name} = NOT_A_VALID_PARAMETER_MSG;
382 0           return undef;
383             }
384              
385             # if there is a value for this parameter, return it
386 0 0         if (defined($Value{$name}) ) {
387 0           $error_code{$function_name} = NO_ERROR_CODE;
388 0           $error_msg{$function_name} = NO_ERROR_MSG;
389 0           return $Value{$name};
390             }
391              
392             # parameter exists, but no value has been assigned
393 0           $error_code{$function_name} = NO_VALUE_ASSIGNED_CODE;
394 0           $error_msg{$function_name} = NO_VALUE_ASSIGNED_MSG;
395 0           return undef;
396             }
397              
398             =head2 parameter_set_by
399              
400             indicates how the parameter value was set.
401             Input : the name of the paramter
402             Output: one of the following codes indicating how the parameter was set:
403             - not set at all (NOT_SET),
404             - set to a default value (DEFAULT),
405             - set by the command line (COMMAND_LINE),
406             - set by the configuraiton file (CONFIG_FILE),
407             - set externally using the set_paramater function (SET_FUNCTION)
408             - or on error, (SET_ERROR) and the error_code and error_message are set
409             =cut
410             sub parameter_set_by {
411 0     0 1   my $name = shift;
412              
413             # set function name for error reporting
414 0           my $function_name = $function_names[2];
415              
416             # check we got a the name of some parameter
417 0 0         if (!defined($name)) {
418 0           $error_code{$function_name} = NO_PARAMETER_SPECIFIED_CODE;
419 0           $error_msg{$function_name} = NO_PARAMETER_SPECIFIED_MSG;
420 0           return SET_ERROR;
421             }
422              
423             # check the name matches a parameter for this program
424             # note a parameter may or may not have an assigned value,
425             # but every valid parameter must have a type
426 0 0         if (!defined($Type{$name}) ) {
427 0           $error_code{$function_name} = NOT_A_VALID_PARAMETER_CODE;
428 0           $error_msg{$function_name} = $name.NOT_A_VALID_PARAMETER_MSG;
429 0           return SET_ERROR;
430             }
431              
432             # the SetBy value is initially NOT_SET and should always be defined
433 0 0         if (!defined($SetBy{$name}) ) {
434 0           $error_code{$function_name} = UNDEFINED_SETBY_CODE;
435 0           $error_msg{$function_name} = UNDEFINED_SETBY_MSG;
436 0           return SET_ERROR;
437             }
438              
439             # if the value doesn't matches any of our SetBY values, return an error
440 0 0         if (invalidSetByField($SetBy{$name}) ) {
441 0           $error_code{$function_name} = INVALID_SETBY_CODE;
442 0           $error_msg{$function_name} = INVALID_SETBY_MSG.$SetBy{$name};
443 0           return SET_ERROR;
444             }
445            
446             # the SetBy value does not match any of our expected values....
447 0           $error_code{$function_name} = NO_ERROR_CODE;
448 0           $error_msg{$function_name} = NO_ERROR_MSG;
449 0           return $SetBy{$name};
450             }
451            
452             =head2 set_parameter
453              
454             Sets a parameter to the specified value.
455              
456             Configuration parameters are typically set by a combination of default value,
457             command line options, and configuration file options. This function allows
458             the caller to over-ride all this and force a parameter to the specified value.
459              
460             Input : the name of the paramter and the value for the paramter
461             Output: 0 on success, 1 on error and sets error_code and error_message
462             =cut
463             sub set_parameter {
464 0     0 1   my ($name, $value) = @_;
465              
466             # set function name for error reporting
467 0           my $function_name = $function_names[3];
468              
469             # check we got a the name of some parameter
470 0 0         if (!defined($name)) {
471 0           $error_code{$function_name} = NO_PARAMETER_SPECIFIED_CODE;
472 0           $error_msg{$function_name} = NO_PARAMETER_SPECIFIED_MSG;
473 0           return 1;
474             }
475              
476             # check the name matches a parameter for this program
477             # note a parameter may or may not have an assigned value,
478             # but every valid parameter must have a type
479 0 0         if (!defined($Type{$name}) ) {
480 0           $error_code{$function_name} = NOT_A_VALID_PARAMETER_CODE;
481 0           $error_msg{$function_name} = $name.NOT_A_VALID_PARAMETER_MSG;
482 0           return 1;
483             }
484              
485             # note the value may be undefined and we set the variable to undef
486            
487             # set the parameter to this value
488 0 0         if (set_parameter_to_value($name, SET_FUNCTION(), $value) ) {
489 0           $error_code{$function_name} = INVALID_VALUE_CODE;
490 0           $error_msg{$function_name} = INVALID_VALUE_MSG;
491 0           return 1;
492             }
493              
494             # return the valid SetBy value
495 0           $error_code{$function_name} = NO_ERROR_CODE;
496 0           $error_msg{$function_name} = NO_ERROR_MSG;
497 0           return 0;
498             }
499              
500             =head2 get_error_code
501              
502             Get the error code
503             Input : the name of the function whose error code we should report
504             Output: the function's error code
505             or NO_FUNCTION_SPECIFIED if the user did not supply a function
506             or INVALID_FUNCTION_SPECIFIED if the user provided an invalid function
507             =cut
508             sub get_error_code {
509 0     0 1   my $function = shift;
510              
511             # check we got a function name
512 0 0         if (!defined($function)) {
513 0           return NO_FUNCTION_SPECIFIED_CODE;
514             }
515              
516             # check this is one of our exported function names
517 0 0         if (!defined($error_code{$function}) ) {
518 0           return INVALID_FUNCTION_SPECIFIED_CODE;
519             }
520              
521 0           my $code = $error_code{$function};
522 0           return $code;
523              
524             }
525              
526             =head2 get_error_message
527              
528             Get the error message
529             Input : the name of the function whose error message we should report
530             Output: the function's error message
531             or NO_FUNCTION_SPECIFIED if the user did not supply a function
532             or INVALID_FUNCTION_SPECIFIED if the user provided an invalid function
533             =cut
534             sub get_error_message {
535 0     0 1   my $function = shift;
536              
537             # check we got a function name
538 0 0         if (!defined($function)) {
539 0           return NO_FUNCTION_SPECIFIED_MSG;
540             }
541              
542             # check this is one of our exported function names
543 0 0         if (!defined($error_msg{$function}) ) {
544 0           return INVALID_FUNCTION_SPECIFIED_MSG."$function";
545             }
546              
547 0           my $msg = $error_msg{$function};
548 0           return $msg;
549             }
550              
551             =head2 get_error_msg
552              
553             Get the error message
554              
555             This function is identical to get_error_message
556             =cut
557             sub get_error_msg {
558 0     0 1   my $msg = shift;
559 0           return get_error_message($msg);
560             }
561              
562             ### ------------------ These functions are not exported -------------
563              
564             # initialize a parameter and set its default value, if default was provided
565             sub create_param {
566 0     0 0   my $params = shift;
567              
568             # set function name for error reporting
569 0           my $function_name = $function_names[4];
570              
571             # check we have some parameter to create
572 0 0         if (!defined($params)) {
573 0           $error_code{$function_name} = PARAMETER_CREATION_ERROR_CODE;
574 0           $error_msg{$function_name}= PARAMETER_CREATION_ERROR_MSG;
575 0           return 1;
576             }
577            
578             # convert our input to a hash
579 0           my %new_param = %$params;
580              
581             # check the parameter has a name
582 0           my $name = $new_param{"Name"};
583 0 0         if (!defined($name) ) {
584 0           $error_code{$function_name} = PARAMETER_CREATION_MISSING_NAME_CODE;
585 0           $error_msg{$function_name}= PARAMETER_CREATION_MISSING_NAME_MSG;
586 0           return 1;
587             }
588              
589             # check the parameter name is not a reserved name
590 0 0 0       if ((lc($name) eq "h") || (lc($name) eq "help") ) {
591 0           $error_code{$function_name} = PARAMETER_CREATION_NO_H_OPT_CODE;
592 0           $error_msg{$function_name}= PARAMETER_CREATION_NO_H_OPT_MSG;
593 0           return 1;
594             }
595              
596             # check the parameter has a type
597 0           my $type = $new_param{"Type"};
598 0 0         if (!defined($type) ) {
599 0           $error_code{$function_name} = PARAMETER_CREATION_MISSING_TYPE_CODE;
600 0           $error_msg{$function_name} = PARAMETER_CREATION_MISSING_TYPE_MSG;
601 0           return 1;
602             }
603              
604             # special handling for the config file. it is already set default, but
605             # the user can specify a default or description
606 0 0 0       if ((lc($name) eq "c") || (lc($name) eq CONFIG_FILE_PARAMETER_NAME) ) {
607 0 0         if ($new_param{"Type"} != FILE ) {
608 0           $error_code{$function_name} =
609             PARAMETER_CREATION_INVALID_CONFIG_FILE_TYPE_CODE;
610 0           $error_msg{$function_name}=
611             PARAMETER_CREATION_INVALID_CONFIG_FILE_TYPE_MSG;
612 0           return 1;
613             }
614             }
615              
616             # make sure the type is valid and set the type
617 0 0         if (set_type($name, $new_param{"Type"}) ) {
618 0           $error_code{$function_name} = PARAMETER_CREATION_INVALID_TYPE_CODE;
619 0           $error_msg{$function_name} = PARAMETER_CREATION_INVALID_TYPE_MSG;
620 0           return 1;
621             }
622              
623             # note the parameter value is not yet set
624 0           $SetBy{$name} = NOT_SET;
625              
626              
627             # extract optional elements for the parameter
628 0           for my $element ( keys %new_param ) {
629 0 0 0       if ($element eq "Description") {
    0          
    0          
630 0           $Description{$name} = $new_param{$element};
631             } elsif ($element eq "Default") {
632 0           $Default{$name} = $new_param{$element};
633 0 0         if (set_parameter_to_value($name, DEFAULT(), $Default{$name}) ) {
634 0           $error_code{$function_name} =
635             PARAMETER_CREATION_INVALID_DEFAULT_CODE;
636 0 0         if(exists($new_param{Name})){
637 0           $error_msg{$function_name} =
638             PARAMETER_CREATION_INVALID_DEFAULT_MSG.
639             " for \"".$new_param{Name}."\"";
640             }
641             else{
642 0           $error_msg{$function_name} =
643             PARAMETER_CREATION_INVALID_DEFAULT_MSG;
644             }
645 0           return 1;
646             }
647 0           $SetBy{$name} = DEFAULT;
648             } elsif (( $element ne "Name" ) && ($element ne "Type") ) {
649 0           $error_code{$function_name} =
650             PARAMETER_CREATION_INVALID_ELEMENT_CODE;
651 0           $error_msg{$function_name} =
652             PARAMETER_CREATION_INVALID_ELEMENT_MSG;
653 0           return 1;
654             }
655             }
656            
657             # successfully created the new parameter and set the default value
658 0           $error_code{$function_name} = NO_ERROR_CODE;
659 0           $error_msg{$function_name} = NO_ERROR_MSG;
660 0           return 0;
661             }
662              
663              
664             # read the command line and set the parameters based on command line settings
665             # print a usage message and exit if the command line parameters are invalid
666             sub read_command_line {
667              
668             # set function name for error reporting
669 0     0 0   my $function_name = $function_names[5];
670              
671             # construct the options for GetOpt
672             # automaticaly include [-h] [-help] [-c CONFIG_FILE_PARAMETER_NAME]
673 0           my $help;
674             my %cli_value;
675 0           my %cli = ('h|help' => \$help,
676             'c|'.CONFIG_FILE_PARAMETER_NAME().'=s'
677             => \$cli_value{CONFIG_FILE_PARAMETER_NAME()} );
678              
679             # construct the usage message
680             # automaticaly include [-h] [-help] [-c configfile] in the usage message
681 0           my $usage = "Usage: ".$0." [-h] [-c configuration_file]";
682 0           my $description = "";
683              
684             # for each parameter, add it to the options for GetOpt and the usage
685 0           my $next_option;
686 0           for my $name ( keys %Type ) {
687             # every Type should have a GetOpt Parameter
688 0 0         if (!defined($GETOPT_PARAM_FOR_TYPE{$Type{$name}} ) ) {
689 0           $error_code{$function_name} =
690             COMMAND_LINE_USAGE_CONSTRUCTION_ERROR_CODE;
691 0           $error_msg{$function_name} =
692             COMMAND_LINE_USAGE_CONSTRUCTION_ERROR_MSG;
693 0           return 1;
694             }
695 0           $next_option = $name.$GETOPT_PARAM_FOR_TYPE{$Type{$name}};
696 0           $cli{$next_option} = \$cli_value{$name};
697            
698             # every Type should have a string to display in the usage message
699 0 0         if (!defined($USAGE_MSG_FOR_TYPE{$Type{$name}} ) ) {
700 0           $error_code{$function_name} =
701             COMMAND_LINE_USAGE_CONSTRUCTION_ERROR_CODE;
702 0           $error_msg{$function_name} =
703             COMMAND_LINE_USAGE_CONSTRUCTION_ERROR_MSG;
704 0           return 1;
705             }
706             # add this parameter along with its type to the usage message
707 0           $usage .= " [-$name ".$USAGE_MSG_FOR_TYPE{$Type{$name}}."]";
708             # if this paramater has a description, add that as well
709 0 0         if (defined($Description{$name}) ) {
710 0           $description .= " [-$name ".$USAGE_MSG_FOR_TYPE{$Type{$name}}.
711             "] ".$Description{$name};
712             # if it has a description and default value, add the default
713 0 0         if (defined($Default{$name}) ) {
714 0           $description .= " (Default is ".$Default{$name}.")";
715             }
716             # each description message is one line
717 0           $description .= "\n";
718             }
719             }
720             # append the descriptions to our usage message
721 0           $usage .= "\n\n".$description;
722              
723             # call Get Options with our parameters and usage message
724 0           my $result = GetOptions (%cli);
725 0 0 0       if ($result == 0 || defined($help) ) {
726 0           die $usage;
727             }
728            
729             # for each command line option set, try to set its value to the users value
730 0           for my $opt ( keys %cli_value ) {
731             # if the user supplied a value on the command line
732 0 0         if (defined($cli_value{$opt}) ) {
733             # set the parameter to this value
734 0 0         if (set_parameter_to_value($opt,COMMAND_LINE(),$cli_value{$opt})){
735 0           $error_code{$function_name} = INVALID_VALUE_CODE;
736 0           $error_msg{$function_name} = INVALID_VALUE_MSG;
737 0           return 1;
738             }
739 0           $SetBy{$opt} = COMMAND_LINE;
740             }
741             }
742              
743             # succesfully read and set all the CLI values
744 0           $error_code{$function_name} = NO_ERROR_CODE;
745 0           $error_msg{$function_name} = NO_ERROR_MSG;
746 0           return 0;
747             }
748              
749             # read the config file and set the parameters accordingly
750             sub read_config_file {
751             # set function name for error reporting
752 0     0 0   my $function_name = $function_names[6];
753              
754             # make sure we have a config file
755 0 0         if (!defined($Value{CONFIG_FILE_PARAMETER_NAME()}) ) {
756 0           return 0;
757             }
758              
759             # if the config file doesn't exist
760 0 0         if (!-e $Value{CONFIG_FILE_PARAMETER_NAME()}) {
761 0           $error_code{$function_name} = CONFIG_FILE_NOT_FOUND_CODE;
762 0           $error_msg{$function_name} = CONFIG_FILE_NOT_FOUND_MSG;
763 0           return 1;
764             }
765              
766             # open the config file for reading
767 0           my $conf_fh;
768 0 0         if (!open($conf_fh, $Value{CONFIG_FILE_PARAMETER_NAME()})) {
769 0           $error_code{$function_name} = CONFIG_FILE_OPEN_FAILED_CODE;
770 0           $error_msg{$function_name} = CONFIG_FILE_OPEN_FAILED_MSG;
771 0           return 1;
772             }
773              
774             # Start reading the file.
775 0           my $line;
776 0           my $line_count = 0;
777 0           my @line_elements;
778             my $name;
779 0           my $value;
780 0           while ($line = <$conf_fh>) {
781 0           $line_count++;
782              
783             # Remove any trailing white space.
784 0           chomp($line);
785 0           $line =~ s/^\s+//g;
786              
787             # If the line starts with a #, skip it.
788 0 0         if ($line =~ /^\s*#/) {
789 0           next;
790             }
791              
792             # If the line is blank, skip it.
793 0 0         if ($line =~ /^$/) {
794 0           next;
795             }
796              
797              
798             # Split line to get parameter and value.
799 0           @line_elements = split(/\=/, $line);
800              
801 0 0         if (@line_elements != 2) {
802 0           $error_code{$function_name} = CONFIG_FILE_INVALID_LINE_CODE;
803 0           $error_msg{$function_name} = CONFIG_FILE_INVALID_LINE_MSG.
804             "at line $line_count,file $Value{CONFIG_FILE_PARAMETER_NAME()}";
805 0           close($conf_fh);
806 0           return 1;
807             }
808            
809 0           $name = $line_elements[0];
810 0           $value = $line_elements[1];
811              
812             # Remove any spaces before and after the = sign.
813 0           $name =~ s/\s+$//g;
814 0           $value =~ s/^\s+//g;
815              
816             # check the name matches a parameter for this program
817 0 0         if (!defined($SetBy{$name}) ) {
818 0           $error_code{$function_name} = NOT_A_VALID_PARAMETER_CODE;
819 0           $error_msg{$function_name} = $name.NOT_A_VALID_PARAMETER_MSG;
820 0           return 1;
821             }
822            
823             # command line always takes precedence over the config file setting
824 0 0         if ($SetBy{$name} == COMMAND_LINE) {
825 0           next;
826             }
827              
828             # set the parameter to this value
829 0 0         if (set_parameter_to_value($name, CONFIG_FILE(), $value) ) {
830 0           $error_code{$function_name} = INVALID_VALUE_CODE;
831 0           $error_msg{$function_name} = INVALID_VALUE_MSG;
832 0           return 1;
833             }
834 0           $SetBy{$name} = CONFIG_FILE;
835              
836             }
837              
838             # close the file and return success
839 0           close($conf_fh);
840 0           $error_code{$function_name} = NO_ERROR_CODE;
841 0           $error_msg{$function_name} = NO_ERROR_MSG;
842 0           return 0;
843             }
844              
845             # determine if a SetBy number is valid
846             # return 0 if the SetBy number is allowed/valid,
847             # return 1 if not allowed/invalid
848             sub invalidSetByField{
849 0     0 0   my $value = shift;
850              
851             # make sure we have a possible value to check
852 0 0         if (!defined($value)) {
853 0           return 1;
854             }
855              
856             # check against all of our approved SetBy values
857 0           for my $approved ( @SETBY_VALUES ) {
858 0 0         if ($value == $approved) {
859 0           return 0;
860             }
861             }
862              
863             # didn't match any approved values so return not allowed/invalid
864 0           return 1;
865             }
866              
867             # set the type for a parameter.
868             # check the type is a supported value and return 0, return 1 on error
869             sub set_type {
870 0     0 0   my ($name, $type) = @_;
871              
872             # make sure we have the parameter name
873 0 0         if (!defined($name)) {
874 0           return 1;
875             }
876              
877             # make sure we have a proposed type
878 0 0         if (!defined($type)) {
879 0           return 1;
880             }
881              
882             # make sure the type is a number
883 0 0         if ($type =~ /\D/) {
884 0           return 1;
885             }
886              
887             # if the type matches any of our SUPPORTED TYPES, set the Type value
888 0           for my $approved ( @SUPPORTED_TYPES ) {
889 0 0         if ($type == $approved) {
890 0           $Type{$name} = $type;
891 0           return 0;
892             }
893             }
894              
895             # the proposed type did not match any SUPPORTED TYPES, return error
896 0           return 1;
897             }
898              
899             # set the value of a parameter and its corresponding SetBy field
900             # the function will make sure this is a valid value for this type of parameter
901             # return 0 on success and 1 on error
902             sub set_parameter_to_value {
903 0     0 0   my ($name, $setby, $value) = @_;
904              
905             # set function name for error reporting
906 0           my $function_name = $function_names[7];
907              
908             # make sure we have the parameter name
909 0 0         if (!defined($name)) {
910 0           $error_msg{$function_name} = "No parameter name given";
911 0           return 1;
912             }
913              
914             # make sure this parameter has a type
915 0 0         if (!defined($Type{$name})) {
916 0           $error_msg{$function_name} = "Parameter doesn't have a type";
917 0           return 1;
918             }
919              
920             # make sure we have a valid SetBy field
921 0 0         if (invalidSetByField($setby)) {
922 0           $error_msg{$function_name} = "Parameter has an invalid SetBy value";
923 0           return 1;
924             }
925              
926             # we can always set the value to undef...
927 0 0         if (!defined($value)) {
928             # indicate who has set the value for this parameter
929 0           $SetBy{$name} = $setby;
930 0           $Value{$name} = undef;
931 0           $error_msg{$function_name} = NO_ERROR_MSG;
932 0           return 0;
933             }
934              
935 0           $SetBy{$name} = $setby;
936             # set the value based on the type
937 0 0         if ($Type{$name} == ADDRESS) {
    0          
    0          
    0          
    0          
    0          
938 0           return set_address($name, $value);
939             } elsif ($Type{$name} == PORT) {
940 0           return set_port($name, $value);
941             } elsif ($Type{$name} == FILE) {
942 0           return set_file($name, $value);
943             } elsif ($Type{$name} == BOOLEAN) {
944 0           return set_boolean($name, $value);
945             } elsif ($Type{$name} == STRING) {
946 0           return set_string($name, $value);
947             } elsif ($Type{$name} == UNSIGNED_INT) {
948 0           return set_uint($name, $value);
949             } else {
950             # unsupported type
951 0           $error_msg{$function_name} = "Parameter has an unsupported type";
952 0           return 1;
953             }
954              
955             # this code should never be reached...
956 0           return 1;
957             }
958              
959             # set an address value for this parameter
960             # verify this really is an IP address. return 0 on succcess and 1 on failure
961             sub set_address {
962 0     0 0   my ($name, $value) = @_;
963              
964             # set function name for error reporting
965 0           my $function_name = $function_names[7];
966              
967             # make sure we have the parameter name
968 0 0         if (!defined($name)) {
969 0           $error_msg{$function_name} = "No parameter name given";
970 0           return 1;
971             }
972              
973             # make sure we have a value
974 0 0         if (!defined($value)) {
975 0           $error_msg{$function_name} = "No parameter value given";
976 0           return 1;
977             }
978              
979             # the Perl::Net module has nice address checkers, but we wanted to
980             # avoid a dependency....
981              
982             # check if we are an IPv4 address
983 0 0         if ($value =~ /\./) {
984 0           my @v4 = split(/\./, $value);
985             # we should have 4 elements (0, 1, 2, and 3)
986 0 0         if ($#v4 != 3) {
987 0           $error_msg{$function_name}="IPv4 address must be in form A.B.C.D.";
988 0           return 1;
989             }
990             # make sure each is a number between 0 and 255
991 0           foreach my $v4num (@v4) {
992 0 0         if ($v4num =~ /\D/) {
993             # not a number or out of range
994 0           $error_msg{$function_name} =
995             "IPv4 address contains a non-integer.";
996 0           return 1;
997             }
998             # make sure it is in range
999 0 0 0       if ( ($v4num < 0) || ($v4num > 255) ) {
1000 0           $error_msg{$function_name} =
1001             "IPv4 octets must be between 0 and 255.";
1002 0           return 1;
1003             }
1004             }
1005             # we have A.B.C.D where A, B, C, D are all numbers between 0 and 255
1006 0           $Value{$name} = $value;
1007 0           $error_msg{$function_name} = NO_ERROR_MSG;
1008 0           return 0;
1009             }
1010            
1011             # check if we are a valid IPv6 address
1012 0 0         if ($value =~ /\:/) {
1013 0           my @v6 = split(/\:/, $value);
1014             # we might be an IPv6 address, make sure each element is a hex number
1015 0           foreach my $v6num (@v6) {
1016             # check we have less than 4 chars per nibble
1017 0           my $len = length($v6num);
1018 0 0         if ($len > 4) {
1019 0           $error_msg{$function_name} =
1020             "IPv6 nibble must be at most 4 chars long.";
1021 0           return 1;
1022             }
1023             # check the nibble is a hex value
1024 0 0         if ($v6num !~ /[0-9a-f]{$len}/i) {
1025             # not a number or out of range
1026 0           $error_msg{$function_name} =
1027             "Possible IPv6 address, but nibble is not hex value.";
1028 0           return 1;
1029             }
1030             }
1031             # we have hex numbers seperated by : values so call it valid v6
1032 0           $Value{$name} = $value;
1033 0           $error_msg{$function_name} = NO_ERROR_MSG;
1034 0           return 0;
1035             }
1036              
1037             # the value is not valid IPv4 or IPv6
1038 0           $error_msg{$function_name} =
1039             "Address must be an IPv4 address or an IPv6 address.";
1040 0           return 1;
1041             }
1042              
1043             # set a port value for this parameter
1044             # verify this really is a valid port. return 0 on succcess and 1 on failure
1045             sub set_port {
1046 0     0 0   my ($name, $value) = @_;
1047              
1048             # set function name for error reporting
1049 0           my $function_name = $function_names[7];
1050              
1051             # make sure we have the parameter name
1052 0 0         if (!defined($name)) {
1053 0           $error_msg{$function_name} = "No parameter name given";
1054 0           return 1;
1055             }
1056              
1057             # make sure we have a value
1058 0 0         if (!defined($value) ) {
1059 0           $error_msg{$function_name} = "No parameter value given";
1060 0           return 1;
1061             }
1062              
1063             # make sure it is a number
1064 0 0         if ($value =~ /\D/) {
1065             # not a number or out of range
1066 0           $error_msg{$function_name} = "Port must be a positive number.";
1067 0           return 1;
1068             }
1069            
1070             # make sure it is in range
1071 0 0 0       if ( ($value < 0) || ($value > 65535) ) {
1072 0           $error_msg{$function_name} = "Port must be in the range 0 to 65,536.";
1073 0           return 1;
1074             }
1075              
1076             # the value is valid so set it
1077 0           $Value{$name} = $value;
1078 0           $error_msg{$function_name} = NO_ERROR_MSG;
1079 0           return 0;
1080             }
1081              
1082             # set a file value for this parameter
1083             # verify this really is a file or directory.
1084             # return 0 on succcess and 1 on failure
1085             sub set_file {
1086 0     0 0   my ($name, $value) = @_;
1087              
1088             # set function name for error reporting
1089 0           my $function_name = $function_names[7];
1090              
1091             # make sure we have the parameter name
1092 0 0         if (!defined($name)) {
1093 0           $error_msg{$function_name} = "No parameter name given";
1094 0           return 1;
1095             }
1096              
1097             # make sure we have a value
1098 0 0         if (!defined($value) ) {
1099 0           $error_msg{$function_name} = "No parameter value given";
1100 0           return 1;
1101             }
1102              
1103             # we accept any string at all...
1104              
1105             # the value is valid so set it
1106 0           $Value{$name} = $value;
1107 0           $error_msg{$function_name} = NO_ERROR_MSG;
1108 0           return 0;
1109             }
1110              
1111             # set a boolean value for this parameter
1112             # verify this really is a boolean value. return 0 on succcess and 1 on failure
1113             sub set_boolean {
1114 0     0 0   my ($name, $value) = @_;
1115              
1116             # set function name for error reporting
1117 0           my $function_name = $function_names[7];
1118              
1119             # make sure we have the parameter name
1120 0 0         if (!defined($name)) {
1121 0           $error_msg{$function_name} = "No parameter name given";
1122 0           return 1;
1123             }
1124              
1125             # make sure we have a value
1126 0 0         if (!defined($value) ) {
1127 0           $error_msg{$function_name} = "No parameter value given";
1128 0           return 1;
1129             }
1130              
1131             # make sure it is a number
1132 0 0         if ($value =~ /\D/) {
1133             # not a number or out of range
1134 0           $error_msg{$function_name} = "Boolean must be 0 or 1.";
1135 0           return 1;
1136             }
1137            
1138             # the value could be false...
1139 0 0         if ($value == 0) {
1140 0           $Value{$name} = 0;
1141 0           $error_msg{$function_name} = NO_ERROR_MSG;
1142 0           return 0;
1143             }
1144              
1145             # or the value could be true...
1146 0 0         if ($value == 1) {
1147 0           $Value{$name} = 1;
1148 0           $error_msg{$function_name} = NO_ERROR_MSG;
1149 0           return 0;
1150             }
1151              
1152             # or the value is invalid...
1153 0           $error_msg{$function_name} = "Boolean must be 0 or 1.";
1154 0           return 1;
1155             }
1156              
1157             # set a string value for this parameter
1158             # verify this really is a string value. return 0 on succcess and 1 on failure
1159             sub set_string {
1160 0     0 0   my ($name, $value) = @_;
1161              
1162             # set function name for error reporting
1163 0           my $function_name = $function_names[7];
1164              
1165             # make sure we have the parameter name
1166 0 0         if (!defined($name)) {
1167 0           $error_msg{$function_name} = "No parameter name given";
1168 0           return 1;
1169             }
1170              
1171             # make sure we have a value
1172 0 0         if (!defined($value)) {
1173 0           $error_msg{$function_name} = "No parameter value given";
1174 0           return 1;
1175             }
1176              
1177             # we accept any string at all...
1178              
1179             # this is a valid value
1180 0           $Value{$name} = $value;
1181 0           $error_msg{$function_name} = NO_ERROR_MSG;
1182 0           return 0;
1183             }
1184              
1185             # set an unsigned integer value for this parameter
1186             # verify this really is an unsigned interger value.
1187             # return 0 on succcess and 1 on failure
1188             sub set_uint {
1189 0     0 0   my ($name, $value) = @_;
1190              
1191             # set function name for error reporting
1192 0           my $function_name = $function_names[7];
1193              
1194             # make sure we have the parameter name
1195 0 0         if (!defined($name)) {
1196 0           $error_msg{$function_name} = "No parameter name given";
1197 0           return 1;
1198             }
1199              
1200             # make sure we have a value
1201 0 0         if (!defined($value) ) {
1202 0           $error_msg{$function_name} = "No parameter value given";
1203 0           return 1;
1204             }
1205              
1206             # make sure it is a number
1207 0 0         if ($value =~ /\D/) {
1208             # not a number or out of range
1209 0           $error_msg{$function_name} = "Unsigned Int must be a postive number";
1210 0           return 1;
1211             }
1212            
1213             # make sure it is in range
1214 0 0         if ($value < 0) {
1215 0           $error_msg{$function_name} = "Unsiged Int must not be less than 0.";
1216 0           return 1;
1217             }
1218              
1219             # the value is valid so set it
1220 0           $Value{$name} = $value;
1221 0           $error_msg{$function_name} = NO_ERROR_MSG;
1222 0           return 0;
1223             }
1224              
1225             =head2 RETURN VALUES AND ERROR CODES
1226              
1227             configure and set_parameter return 0 on success and 1 on error.
1228              
1229             parameter_value returns the value on success and undef on error.
1230              
1231             parameter_set_by returns an integer indicating who set the value
1232             and on error it returns BGPmon::Configure::SET_ERROR
1233              
1234             In the event of an error, an error code and error
1235             message can be obtained using
1236             $code = get_error_code("function_name");
1237             $msg = get_error_msg("function_name");
1238              
1239             The following error codes are defined:
1240              
1241             0 - No Error
1242             'No Error'
1243              
1244             1 - No Function Specified in get_error_code/get_error_msg.
1245             'Error reporting function called without specifying the function.'
1246              
1247             2 - Invalid Funtion in get_error_code/get_error_msg.
1248             'Error reporting function called with invalid function name'
1249              
1250             3 - There wasn't a name specified in get_error_code/get_error_msg.
1251             'No parameter name specified'
1252            
1253             4 - Input was not a valid parameter coe in get_error_code/get_error_msg.
1254             'Invalid parameter name'
1255              
1256             5 - No value has been assigned to the paramter.
1257             'No value has been assigned to this parameter'
1258            
1259             6 - The parameter must be given a Set By command but wasn't.
1260             'The SetBy field of the parameter is undefined'
1261            
1262             7 - Invalid SetBy field was given.
1263             'The SetBy field of the parameter is invalid.'
1264              
1265             8 - An invalid value was given for a parameter.
1266             'Invalid value for parameter'
1267              
1268             9 - There were no parameters to create.
1269             'Error creating the paramter - missing parameter hash';
1270              
1271             10 - The parameter is missing a name.
1272             'Error creating the paramter - parameter name is missing'
1273              
1274             11 - The parameter is missing a type.
1275             'Error creating the paramter - parameter name is missing'
1276              
1277             12 - The parameter was given an invalid type.
1278             'Error creating the paramter - invalid type '
1279              
1280             13 - The parameter was given an invalid or unsupported element in the hash.
1281             'Error creating the paramter - invalid element '
1282              
1283             14 - The default attribute given for a parameter is invalid.
1284             'Error creating the paramter - invalid default value '
1285              
1286             15 - The name of the parameter is a reserved name and cannot be used.
1287             'Error creating the paramter - parameter name -h and -help are reserved'
1288              
1289             16 - The configuration file could not be opened.
1290             'Error creating the paramter - config file must be type FILE'
1291              
1292             17 - Parameter wasn't given an GetOpt command.
1293             'Unable to construct usage message for command line'
1294              
1295             19 - The configuration file could not be found.
1296             'Configuration file not found'
1297              
1298             20 - Failed to open the configuration file.
1299             'Failed to open configuration file';
1300              
1301             21 - There was in invalid line in the configuration file.
1302             'Invalid line in configuration file: ';
1303              
1304              
1305             =head1 AUTHOR
1306              
1307              
1308             M.Lawrence Weikum, C<< >>
1309             Dan Massey, C<< >>
1310              
1311             =head1 BUGS
1312              
1313             Please report any bugs or feature requests to C<< bgpmon@netsec.colostate.edu> >>.
1314              
1315             =head1 SUPPORT
1316              
1317             You can find documentation for this module with the perldoc command.
1318              
1319             perldoc BGPmon::Configure
1320             =cut
1321              
1322             =head1 LICENSE AND COPYRIGHT
1323              
1324             Copyright (c) 2012 Colorado State University
1325              
1326             Permission is hereby granted, free of charge, to any person
1327             obtaining a copy of this software and associated documentation
1328             files (the "Software"), to deal in the Software without
1329             restriction, including without limitation the rights to use,
1330             copy, modify, merge, publish, distribute, sublicense, and/or
1331             sell copies of the Software, and to permit persons to whom
1332             the Software is furnished to do so, subject to the following
1333             conditions:
1334              
1335             The above copyright notice and this permission notice shall be
1336             included in all copies or substantial portions of the Software.
1337              
1338             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1339             EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1340             OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1341             NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1342             HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1343             WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1344             FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1345             OTHER DEALINGS IN THE SOFTWARE.\
1346              
1347             File: Configure.pm
1348              
1349             Authors: M. Lawrence Weikum, Dan Massey
1350            
1351             Date: 13 October 2013
1352             =cut
1353              
1354             1;