source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Utils.pm @ 1023

Last change on this file since 1023 was 1023, checked in by nanardon, 12 years ago
  • complete POD

This patch a basic documentation to all functions.
It also add two test to ensure all POD syntax are correct and coverage is full.

  • Property svn:keywords set to Id Rev
File size: 6.1 KB
Line 
1package LATMOS::Accounts::Utils;
2use 5.010000;
3use strict;
4use warnings;
5use Exporter ();
6use vars qw(@ISA @EXPORT_OK @EXPORT);
7use utf8;
8use LATMOS::Accounts::Log;
9use File::Temp qw(tempfile);
10
11our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
12
13=head1 NAME
14
15LATMOS::Accounts::Utils - Utils functions
16
17=head1 FUNCTIONS
18
19=cut
20
21@ISA = qw(Exporter);
22@EXPORT = qw(to_ascii exec_command switch_user run_via_sudo);
23@EXPORT_OK = qw(to_ascii exec_command switch_user run_via_sudo);
24
25=head2 to_ascii($text)
26
27Replace in C<$text> non ascii caracters from iso-8859-15 table to ascii
28equivalent caracter.
29
30=cut
31
32sub to_ascii {
33    my ($text) = @_;
34    return $text unless(defined($text));
35    utf8::decode($text) unless(utf8::is_utf8($text));
36    $text =~ s/œ/oe/g;
37    $text =~ s/Ê/ae/g;
38    $text =~ tr {uàâÀÂÄÀçéÚêëÉÈÊËïîÏÎÞöÎÖÔÌûÛÜć}
39                {uaaaAAAceeeeEEEEiiIIoooOOuuUUc};
40    $text =~ s/([^[:ascii:]])/_/g;
41    $text
42} 
43
44=head2 exec_command($command, $env)
45
46Execute C<$command> and redirect output to log system.
47
48C<$env> is a hashref containing environment variable to set, all variables are
49prefixed by 'LA_'.
50
51=cut
52
53sub exec_command {
54    my ($command, $env) = @_;
55    my $rout = undef;
56    $rout = \$_[2] if(@_ > 2);
57
58    my @exec = ref $command
59        ? (@$command)
60        : ($command);
61    la_log(LA_DEBUG, 'running command `%s\'', join(' ', @exec));
62
63    pipe(my $rh, my $wh);
64    my $pid = fork;
65    if (!defined($pid)) {
66        la_log(LA_ERR, "Can't launch script: cannot fork");
67    } elsif ($pid) {
68        # Father
69        close($wh);
70        my $header;
71        while (<$rh>) {
72            if ($rout) {
73                $$rout .= $_;
74            } else {
75                chomp;
76                if (!$header) {
77                    $header = 1;
78                    la_log(LA_NOTICE, "exec `%s'", join(' ', @exec));
79                }
80                la_log(LA_NOTICE, "output: %s", $_);
81            }
82        }
83        waitpid($pid, 0);
84        if (my $exitstatus = $?) {
85            la_log(LA_ERR, 'command %s exit with status %d',
86                join(' ', @exec), $exitstatus);
87            return;
88        } else {
89            return 1;
90        }
91    } else {
92        # Child
93        close($rh);
94        ( $ENV{LA_MODULE} ) = caller();
95        foreach (keys %{ $env || {} }) {
96            $ENV{"LA_$_"} = $env->{$_};
97        }
98        open(STDOUT, ">&=" . fileno($wh));
99        open(STDERR, ">&=" . fileno($wh));
100        exec(@exec);
101        exit($!);
102    }
103    1
104}
105
106=head2 parse_obj_file($handle)
107
108Read file content from C<$handle> and return hash containing parsed attributes
109
110=cut
111
112sub parse_obj_file {
113    my ($handle) = @_;
114
115    my %attributes;
116    while (my $line = <$handle>) {
117        $line =~ /^#/ and next;
118        chomp($line);
119        my ($attr, $value) = $line =~ /^\s*(\S+):\s*(.*)\s*$/ or
120            die "Malformed input file\n";
121        $value =~ s/\s*$//;
122        $value =~ s/\\n/\n/g;
123        if ($attributes{$attr}) {
124            if (ref $attributes{$attr}) {
125                push(@{ $attributes{$attr} }, $value);
126            } else {
127                my $temp = $attributes{$attr};
128                $attributes{$attr} = [ $temp, $value ];
129            }
130        } else {
131            $attributes{$attr} = $value eq '' ? undef : $value;
132            # Don't remember why this is here
133            #$attr eq 'exported' && !defined $attributes{$attr} and $attributes{$attr} = 1;
134        }
135    }
136    %attributes
137}
138
139=head2 dump_read_temp_file($writecb, $readcb)
140
141Create a temporary file, call C<$writecb()> function, run editor and if file get
142modified call C<$readcb>.
143
144=cut
145
146sub dump_read_temp_file {
147    my ($writecb, $readcb) = @_;
148
149    my ($fh, $filename) = tempfile(CLEANUP => 0);
150    $writecb->($fh) or return;
151    $fh = undef; # closing file
152    my $res;
153   
154    my @stat = stat($filename);
155    while (1) {
156        my $cmd = ($ENV{EDITOR} || 'vi') . " $filename";
157        warn "Running $cmd\n";
158        if (system($cmd) == -1 ) {
159            warn "Cannot run editor $!\n";
160            last;
161        }
162        if ((stat($filename))[9] == $stat[9]) {
163            warn "No change existing\n";
164            last;
165        }
166
167        open($fh, '<', $filename) or return;
168        $res = $readcb->($fh);
169        $fh = undef; # closing again
170        $res < 2 and last;
171    }
172    unlink($filename);
173    $res;
174}
175
176=head2 check_oid_validity($name)
177
178Check C<$name> is suitable to be used as object identifier. Return the error
179text, undef if no error.
180
181=cut
182
183sub check_oid_validity {
184    my ($name) = @_;
185    return "leadind space" if ($name =~ /^\s/);
186    return "trailing space" if ($name =~ /\s$/);
187    return "containing space" if ($name =~ /\s/);
188
189    return;
190}
191
192=head2 check_ug_validity($name)
193
194Check C<$name> is suitable to used as user or group identifier.
195
196=cut
197
198sub check_ug_validity {
199    my ($name) = @_;
200    return "Empty name is not a valid name !"
201        if (!$name);
202    return "first caractere must be a-z"
203        if ($name !~ /^[a-z]/);
204    return "must contain only a-z,0-9"
205        if ($name !~ /^[a-z,0-9,_,-]+$/);
206
207    return check_oid_validity($name);
208}
209
210=head2 switch_user($runas)
211
212Switch effective id of the process to user named C<$runas>
213
214=cut
215
216sub switch_user {
217    my ($runas) = @_;
218
219    if ($< == 0 || $> == 0) {
220        my @info = getpwnam($runas) or do {
221            warn "Can find user $runas";
222            return;
223        };
224        $> = $info[3];
225        return;
226    } else {
227        warn "we are not root";
228    }
229}
230
231=head2 run_via_sudo($runas)
232
233Rerun current programme as C<$runas> user using sudo
234
235=cut
236
237sub run_via_sudo {
238    my ($runas) = @_;
239
240    my @info = getpwnam($runas) or do {
241        warn "Can find user $runas";
242        return;
243    }; 
244    if ($< != $info[3]) {
245        exec('sudo', '-u', $runas, $0, @ARGV) or "Can run $!";
246    }
247}
248
2491;
250
251__END__
252
253=head1 SEE ALSO
254
255L<sudo>
256
257=head1 AUTHOR
258
259Olivier Thauvin, E<lt>olivier.thauvin@aerov.jussieu.frE<gt>
260
261=head1 COPYRIGHT AND LICENSE
262
263Copyright (C) 2008, 2009, 2010, 2011, 2012 CNRS SA/CETP/LATMOS
264
265This library is free software; you can redistribute it and/or modify
266it under the same terms as Perl itself, either Perl version 5.10.0 or,
267at your option, any later version of Perl 5 you may have available.
268
269=cut
Note: See TracBrowser for help on using the repository browser.