PageRenderTime 42ms CodeModel.GetById 6ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/libs/perl/Choicetool/RC/RCFile.pm

#
Perl | 369 lines | 299 code | 41 blank | 29 comment | 17 complexity | 6bd9e52ae70108aed2d619a91a00b337 MD5 | raw file
  1# -*- perl -*-
  2
  3#
  4# RCFile.pm
  5#
  6# Copyright (C) 2008, 2009 Francesco Salvestrini
  7#
  8# This program is free software; you can redistribute it and/or modify
  9# it under the terms of the GNU General Public License as published by
 10# the Free Software Foundation; either version 2 of the License, or
 11# (at your option) any later version.
 12#
 13# This program is distributed in the hope that it will be useful,
 14# but WITHOUT ANY WARRANTY; without even the implied warranty of
 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16# GNU General Public License for more details.
 17#
 18# You should have received a copy of the GNU General Public License along
 19# with this program; if not, write to the Free Software Foundation, Inc.,
 20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 21#
 22
 23package Choicetool::RC::RCFile;
 24
 25use 5.8.0;
 26
 27use warnings;
 28use strict;
 29use diagnostics;
 30
 31use Choicetool::Autoconfig;
 32use Choicetool::Base::Debug;
 33use Choicetool::Base::Trace;
 34use Choicetool::OS::File;
 35
 36sub new ($$)
 37{
 38    my $class    = shift;
 39    my $filename = shift;
 40
 41    assert(defined($class));
 42    assert(defined($filename));
 43
 44    my $self = { };
 45
 46    $self->{FILENAME} = $filename;
 47    $self->{HOSTS}    = { };
 48
 49    bless $self, $class;
 50
 51    return $self;
 52}
 53
 54#
 55# XXX FIXME: This sub is only a sketch, we should output more clearer messages
 56#
 57sub iscorrect ($)
 58{
 59    my $self = shift;
 60
 61    assert(defined($self));
 62
 63    my $found_host = 0;
 64    for my $host (keys(%{$self->{HOSTS}})) {
 65        $found_host = 1;
 66
 67        my $found_login = 0;
 68        for my $login (keys(%{$self->{HOSTS}->{$host}->{LOGIN}})) {
 69
 70            $found_login = 1;
 71            if (!defined(($self->{HOSTS}->{$host}->{LOGIN}->{$login}))) {
 72                warning("Host "              .
 73                        "\`" . $host . "', " .
 74                        "login "             .
 75                        "\`" . $login . "' " .
 76                        "is without a password");
 77                return 1;
 78            }
 79        }
 80
 81        if (!$found_login) {
 82            warning("Host \`" . $host . "' is without a login");
 83            return 1;
 84        }
 85    }
 86
 87    if (!$found_host) {
 88        warning("No hosts defined");
 89        return 1;
 90    }
 91
 92    return 1;
 93}
 94
 95sub load ($)
 96{
 97    my $self = shift;
 98
 99    assert(defined($self));
100
101    debug("Loading RC file");
102
103    my $filename;
104
105    $filename = $self->{FILENAME};
106    assert(defined($filename));
107
108    if (!file_ispresent($filename)) {
109        error("File \`" . $filename . "' is not present");
110        return 0;
111    }
112
113    my $filehandle;
114
115    if (!open($filehandle, "<", $filename)) {
116        error("Cannot open \`$filename' for input");
117        return 0;
118    }
119
120    my $string;
121    my $lineno;
122    my $nodes;
123    my $host;
124    my $login;
125    my $password;
126
127    $host     = undef;
128    $login    = undef;
129    $password = undef;
130    $lineno   = 0;
131    $nodes    = 0;
132
133    debug("Parsing file \`" . $filename . "'");
134    while (<$filehandle>) {
135        $string = $_;
136        if ($string =~ /^[ \t]*\#.*$/) {
137            # Skip comments
138        } elsif ($string =~ /^[ \t]*$/) {
139            # Skip empty lines
140        } elsif ($string =~ /^[ \t]*host[ \t]+(.*)$/) {
141
142            $host     = $1;
143            $login    = undef;
144            $password = undef;
145
146            debug("Got $1");
147
148            assert(defined($host));
149            debug("Got host keyword at line " . $lineno . ", " .
150                  "host = \`" . $host . "'");
151
152            $self->{HOSTS}->{$host} = { };
153
154            $nodes++;
155
156        } elsif ($string =~ /^[ \t]*login[ \t]+(.*)$/) {
157
158            debug("Got $1");
159
160            $login    = $1;
161            $password = undef;
162
163            assert(defined($login));
164            debug("Got login keyword at line " . $lineno . ", " .
165                  "login = \`" . $login . "'");
166
167            if (!defined($host)) {
168                error("Wrong formatted input file \`" . $filename . "'");
169                return 0;
170            }
171
172            #if (defined($self->{HOSTS}->{$host}->{LOGIN}->{$login})) {
173            #   error("Login \`" . $login . "' already defined");
174            #   return 0;
175            #}
176            $self->{HOSTS}->{$host}->{LOGIN}->{$login} = undef;
177
178            $nodes++;
179
180        } elsif ($string =~ /^[ \t]*password[ \t]+(.*)$/) {
181
182            debug("Got $1");
183
184            $password = $1;
185
186            assert(defined($password));
187            debug("Got password keyword at line " . $lineno . ", " .
188                  "password = \`" . $password . "'");
189
190            if (!defined($host)) {
191                error("Wrong formatted input file \`" . $filename . "'");
192                return 0;
193            }
194            if (!defined($login)) {
195                error("Wrong formatted input file \`" . $filename . "'");
196                return 0;
197            }
198
199            #if (defined($self->{HOSTS}->{$host}->{LOGIN}->{$login})) {
200            #   error("Login \`" . $login . "' already defined");
201            #   return 0;
202            #}
203            $self->{HOSTS}->{$host}->{LOGIN}->{$login} = $password;
204
205            $nodes++;
206
207        } else {
208            error("Unknown input line " . $lineno . " in file " .
209                  "\`" . $filename . "'");
210            return 0;
211        }
212
213        $lineno++;
214    }
215    debug("Parsing of \`" . $filename . "' complete");
216
217    close($filehandle);
218
219    if (!$self->iscorrect()) {
220        error("File \`" . $filename . "' has an incorrect format");
221        return 0;
222    }
223
224    debug("Loaded " . $nodes . " nodes");
225
226    return 1;
227}
228
229sub save ($)
230{
231    my $self = shift;
232
233    assert(defined($self));
234
235    debug("Saving RC file");
236
237    if (!$self->iscorrect()) {
238        error("RC Data contains incorrect data");
239        return 0;
240    }
241
242    my $filename;
243
244    $filename = $self->{FILENAME};
245    assert(defined($filename));
246
247    my $filehandle;
248
249    if (!open($filehandle, ">", $filename)) {
250        error("Cannot open \`$filename' for input");
251        return 0;
252    }
253
254    my $nodes;
255
256    $nodes = 0;
257    for my $host (keys(%{$self->{HOSTS}})) {
258        debug("Saving host \`" . $host . "'");
259
260        print $filehandle "host     " . $host . "\n";
261
262        $nodes++;
263
264        for my $login (keys(%{$self->{HOSTS}->{$host}->{LOGIN}})) {
265            debug("Saving login \`" . $login . "'");
266
267            print $filehandle "login    " . $login . "\n";
268
269            $nodes++;
270
271            my $password;
272
273            $password = $self->{HOSTS}->{$host}->{LOGIN}->{$login};
274            if (defined($password)) {
275                debug("Saving password \`" . $password . "'");
276
277                print $filehandle "password " . $password . "\n";
278
279                $nodes++;
280            }
281        }
282
283        print $filehandle "\n";
284    }
285    debug("Saved " . $nodes . " nodes");
286
287    close($filehandle);
288
289    return 1;
290}
291
292sub add ($$$$)
293{
294    my $self     = shift;
295    my $host     = shift;
296    my $login    = shift;
297    my $password = shift;
298
299    assert(defined($self));
300    assert(defined($host));
301    assert(defined($login));
302    assert(defined($password));
303
304    debug("Adding RC entry " .
305          "(\`" . $host . "', \`" . $login . "', \`" . $password . "')");
306
307    if (!defined($self->{HOSTS})) {
308        $self->{HOSTS} = { };
309        debug("HOSTS created")
310    }
311    if (!defined($self->{HOSTS}->{$host})) {
312        $self->{HOSTS}->{$host} = { };
313        debug("HOSTS \`" . $host . "' created")
314    }
315    if (!defined($self->{HOSTS}->{$host}->{LOGIN})) {
316        $self->{HOSTS}->{$host}->{LOGIN} = { };
317        debug("HOSTS \`" . $host . "' LOGIN created")
318    }
319
320    $self->{HOSTS}->{$host}->{LOGIN}->{$login} = $password;
321    debug("HOSTS \`" . $host . "' LOGIN \`" . $login . "' password created " .
322          " with value \`" . $self->{HOSTS}->{$host}->{LOGIN}->{$login} . "'");
323
324    return 1;
325}
326
327sub remove ($$$)
328{
329    my $self     = shift;
330    my $host     = shift;
331    my $login    = shift;
332
333    assert(defined($self));
334    assert(defined($host));
335    assert(defined($login));
336
337    debug("Removing RC entry " .
338          "(\`" . $host . "', \`" . $login . "')");
339
340    delete $self->{HOSTS}->{$host}->{LOGIN}->{$login};
341
342    return 1;
343}
344
345sub foreach ($$)
346{
347    my $self     = shift;
348    my $callback = shift;
349
350    assert(defined($self));
351    assert(defined($callback));
352
353    for my $host (keys(%{$self->{HOSTS}})) {
354        debug("Iterating over host \`" . $host . "'");
355
356        for my $login (keys(%{$self->{HOSTS}->{$host}->{LOGIN}})) {
357            debug("Iterating over login \`" . $login . "'");
358
359            my $password;
360            $password = $self->{HOSTS}->{$host}->{LOGIN}->{$login};
361
362            if (!$callback->($host, $login, $password)) {
363                return;
364            }
365        }
366    }
367}
368
3691;