lilalo

changeset 139:f9d0d35618f8

Удалены файлы из labmaker

Удалены файлы, которые переползли в репозиторий
из проекта labmaker
Если кому-то нужны эти файлы,
они есть в старом CVS-репозитории lilalo.

Удаление лишних файлов ещё полностью
не завершено. Ещё будем удалять
author igor@chub.in
date Mon Jul 21 12:28:13 2008 +0300 (2008-07-21)
parents 93e08c4b54ed
children da99089532ca
files lm lm-install lm-report lm-ssh taillast.pl
line diff
     1.1 --- a/lm	Mon Jul 21 11:24:53 2008 +0300
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,555 +0,0 @@
     1.4 -#!/usr/bin/perl
     1.5 -
     1.6 -
     1.7 -use strict;
     1.8 -use Data::Dumper;
     1.9 -use Switch;
    1.10 -use XML::Simple;
    1.11 -use Getopt::Long;
    1.12 -use utf8;
    1.13 -
    1.14 -use lib "/usr/local/bin";
    1.15 -use l3config;
    1.16 -
    1.17 -our $XMLClass;
    1.18 -our $XMLCourse;
    1.19 -our @Labs;
    1.20 -
    1.21 -our %Machines;          # Machines list from class.xml
    1.22 -our @SelectedMachines;      # Machines list given as the command line argument
    1.23 -
    1.24 -our $Config_File = "labmaker.conf";
    1.25 -our %Config_ = (
    1.26 -    "show_host"     => "no",
    1.27 -
    1.28 -    # Вспомогательные программы
    1.29 -    #"l3-report"    => "./lm-report",
    1.30 -    "l3-report" => "./l3-report",
    1.31 -
    1.32 -    # Каталоги
    1.33 -    "path_lilalo" => "/var/lilalo/",
    1.34 -    "path_classes"  => "/var/lilalo/classes/",
    1.35 -    "path_lablogs"  => "/var/lilalo/lablogs/",
    1.36 -    "courses_path"  => "/var/lilalo/courses/",
    1.37 -    "outpath"   => "/var/lilalo/out/",
    1.38 -    "path_web"  => "/var/www/l3",       # Путь к web-отчётам
    1.39 -    "path_share"    => "./share/",      # Путь к web-отчётам
    1.40 -
    1.41 -    # Файлы
    1.42 -    "runfile"   => "lm.run", 
    1.43 -    "logfile"   => "lm.log", 
    1.44 -
    1.45 -    "class"     => "class",                 # Имя файла класса
    1.46 -    "class_suffix"  => ".xml",              # Cуффикс файла класса
    1.47 -    "classfile" => "",
    1.48 -
    1.49 -    "sshkey"    => "$ENV{HOME}/.ssh/id_dsa.pub",
    1.50 -    "lmssh"     => "./lm-ssh",
    1.51 -    "lminstall" => "./lm-install",
    1.52 -    "ssh_user"  => "root",
    1.53 -);
    1.54 -
    1.55 -our %Run = (
    1.56 -    "lab" => ""
    1.57 -);
    1.58 -
    1.59 -our %Scripts;
    1.60 -
    1.61 -sub load_class;
    1.62 -sub load_config;
    1.63 -sub load_course;
    1.64 -sub load_scripts;
    1.65 -
    1.66 -sub lm_get;
    1.67 -sub lm_next;
    1.68 -sub lm_prev;
    1.69 -sub lm_start;
    1.70 -sub lm_stop;
    1.71 -sub lm_set;
    1.72 -sub lm_do;
    1.73 -sub lm_report;
    1.74 -sub lm_show_hosts;
    1.75 -sub lm_show_email;
    1.76 -sub lm_show_labs;
    1.77 -
    1.78 -sub load_run;
    1.79 -sub save_run;
    1.80 -sub print_log;
    1.81 -sub print_usage_info;
    1.82 -sub main();
    1.83 -
    1.84 -main();
    1.85 -
    1.86 -sub main()
    1.87 -{
    1.88 -    binmode STDOUT, ":utf8";
    1.89 -
    1.90 -    if (! @ARGV) {
    1.91 -        print_usage_info();
    1.92 -        exit(0);
    1.93 -    }
    1.94 -
    1.95 -    if ($ARGV[0] eq "get") {
    1.96 -         lm_get;
    1.97 -         exit(0);
    1.98 -    }
    1.99 -
   1.100 -    init_config();
   1.101 -    #load_config;
   1.102 -    load_run;
   1.103 -    load_scripts;
   1.104 -    load_class;
   1.105 -    load_course;
   1.106 -    
   1.107 -    my $arg = join " ", @ARGV;
   1.108 -
   1.109 -    # Getting @SelectedMachines if any
   1.110 -    if ($arg =~ s/@(.*?)\s//) {
   1.111 -        my $machines = $1;
   1.112 -        my @list = split /,/, $machines;
   1.113 -        for my $interval (@list) {
   1.114 -            my ($first, $last) = split /-/, $interval;
   1.115 -
   1.116 -            push @SelectedMachines, $first;
   1.117 -            while ($first < $last) {
   1.118 -                push @SelectedMachines, ++$first;
   1.119 -            }   
   1.120 -        }
   1.121 -    }
   1.122 -
   1.123 -    # Choose command to do
   1.124 -    switch ($arg) {
   1.125 -        case "next" { lm_next }
   1.126 -        case "prev" { lm_prev }
   1.127 -        case /set / { $arg =~ /set (.*)/; lm_set $1 }
   1.128 -        case "report"   { lm_report }
   1.129 -        case "start"    { lm_start }
   1.130 -        case "stop" { lm_stop }
   1.131 -        case "show hosts" { lm_show_hosts }
   1.132 -        case "show email" { lm_show_email }
   1.133 -        case "show labs" { lm_show_labs }
   1.134 -        case /do /  { $arg =~ /do (.*)/;  lm_do "$1" }
   1.135 -        else        { print_usage_info() }
   1.136 -    }
   1.137 -    save_run;
   1.138 -    exit(0);
   1.139 -}
   1.140 -
   1.141 -sub load_scripts
   1.142 -{
   1.143 -    open (SCRIPTS, "$Config{l3scripts}")
   1.144 -        or die "Cant open l3scripts file: ".$Config{l3scripts}.": $!\n";
   1.145 -    binmode SCRIPTS, ":utf8";
   1.146 -    local $/;
   1.147 -    $_=<SCRIPTS>;
   1.148 -    close(SCRIPTS);
   1.149 -
   1.150 -    %Scripts = ("empty-element", split (/###(.*)\n/));
   1.151 -    delete($Scripts{"empty-element"});
   1.152 -
   1.153 -}
   1.154 -
   1.155 -sub load_config
   1.156 -{
   1.157 -    my %file_config;
   1.158 -    my %argv_config;
   1.159 -    #read_config_file(\%file_config, $Config_File);
   1.160 -    GetOptions(\%argv_config, map "$_=s", keys %Config);
   1.161 -    %Config = (%Config, %file_config, %argv_config);
   1.162 -}
   1.163 -
   1.164 -sub load_course
   1.165 -{
   1.166 -    $XMLCourse = XMLin($Config{"courses_path"}.$XMLClass->{"course"}.".xml", ForceArray => 1 )  
   1.167 -        or die "Can't open file of the course ",$XMLClass->{"course"}," [with .xml extension]\n";
   1.168 -#   print Dumper($XMLCourse);
   1.169 -    for my $lab (@{$XMLCourse->{"module"}}) {
   1.170 -        push @Labs, $lab->{"code"};
   1.171 -    }
   1.172 -}
   1.173 -
   1.174 -sub load_class
   1.175 -{
   1.176 -    my $classfile =
   1.177 -    $Config{"classfile"} || 
   1.178 -    $Config{"path_classes"}."/".$Config{"class"}.$Config{"class_suffix"};
   1.179 -    $XMLClass = XMLin($classfile , ForceArray => [ 'student' ] )  
   1.180 -        or die "Can't open file of the class ",$classfile,"\n";
   1.181 -
   1.182 -    for my $student (@{$XMLClass->{"student"}}) {
   1.183 -        $Machines{$student->{"host"}} = {
   1.184 -            "name"  => "$student->{firstname} $student->{surname}",
   1.185 -            "firstname" => "$student->{firstname}",
   1.186 -            "user"  => "$student->{user}",
   1.187 -            "email" => "$student->{email}",
   1.188 -            "student" => $student,
   1.189 -        }   
   1.190 -    }
   1.191 -#   print Dumper($XMLClass);
   1.192 -#   print Dumper(\%Machines);
   1.193 -}
   1.194 -
   1.195 -sub lm_get
   1.196 -{
   1.197 -    print "Getting class description file...";
   1.198 -    if (system("cd $Config{path_classes}; rm -f class.xml ; wget xgu.ru/l3/classes/class.xml") ==0 )
   1.199 -    {
   1.200 -        print "Ok\n";
   1.201 -    } 
   1.202 -    else {
   1.203 -        die "Can't load class file\n"
   1.204 -    }
   1.205 -}
   1.206 -
   1.207 -
   1.208 -sub lm_next
   1.209 -{
   1.210 -    for(my $i=0; $i<=$#Labs; $i++){
   1.211 -        if ( $Labs[$i] eq $Run{"lab"} ) {
   1.212 -            if ($i < $#Labs) {
   1.213 -                lm_set($Labs[$i+1]);
   1.214 -                return ;
   1.215 -            } else {
   1.216 -                die "Lab ", $Run{"lab"}, " is the last. Switch to next lab is impossible"
   1.217 -            }
   1.218 -        }
   1.219 -        
   1.220 -    }
   1.221 -    die "Lab ", $Run{"lab"}, " not found. Don't know which is next"
   1.222 -}
   1.223 -
   1.224 -sub lm_prev
   1.225 -# Switch to previous lab
   1.226 -{
   1.227 -    for(my $i=0; $i<=$#Labs; $i++){
   1.228 -        if ( $Labs[$i] eq $Run{"lab"} ) {
   1.229 -            if ($i > 0) {
   1.230 -                lm_set($Labs[$i-1]);
   1.231 -                return ;
   1.232 -            } else {
   1.233 -                die "Lab ", $Run{"lab"}, " is the first. Switch to previous lab is impossible"
   1.234 -            }
   1.235 -        }
   1.236 -        
   1.237 -    }
   1.238 -    die "Lab ", $Run{"lab"}, " not found. Don't know which is previous"
   1.239 -}
   1.240 -
   1.241 -sub lm_set
   1.242 -# Switch to $_[0] lab
   1.243 -# FIXME
   1.244 -{
   1.245 -    my $lab = shift;
   1.246 -    print "Current lab is $lab\n";
   1.247 -    $Run{"lab"} = "$lab";
   1.248 -    lm_do "setlab", $lab;
   1.249 -}
   1.250 -
   1.251 -
   1.252 -sub lm_start
   1.253 -# Start new training day
   1.254 -{
   1.255 -    print_log(`date`." STARTED\n");
   1.256 -    if ($Run{"lab"}) {
   1.257 -        lm_next;
   1.258 -    }
   1.259 -    else
   1.260 -    {
   1.261 -        # First lab in the course
   1.262 -        lm_set($Labs[0]);
   1.263 -    }
   1.264 -}
   1.265 -
   1.266 -sub lm_stop
   1.267 -# Stop this training day
   1.268 -{
   1.269 -    print_log(`date`." STOPPED\n");
   1.270 -}
   1.271 -
   1.272 -
   1.273 -sub lm_show_hosts
   1.274 -# Show hosts used to run a commands
   1.275 -{
   1.276 -    my $i=1;
   1.277 -    for my $m (sort keys %Machines) {
   1.278 -        if (!@SelectedMachines || grep /^$i$/, @SelectedMachines) {
   1.279 -            print "($i)","\t",$m,"\t",$Machines{$m}->{"name"},"\n";
   1.280 -        }   
   1.281 -        $i++;
   1.282 -    }
   1.283 -}
   1.284 -
   1.285 -sub lm_show_email
   1.286 -# Show hosts used to run a commands
   1.287 -{
   1.288 -    my $i=1;
   1.289 -    for my $m (sort keys %Machines) {
   1.290 -        if (!@SelectedMachines || grep /^$i$/, @SelectedMachines) {
   1.291 -            print $Machines{$m}->{"email"},"\t",$Machines{$m}->{"name"},"\n";
   1.292 -        }   
   1.293 -        $i++;
   1.294 -    }
   1.295 -}
   1.296 -
   1.297 -sub lm_show_labs
   1.298 -# Show hosts used to run a commands
   1.299 -{
   1.300 -    my $i=1;
   1.301 -    for my $lab (@Labs) {
   1.302 -        print $lab;
   1.303 -        print "*" if $lab eq $Run{"lab"};
   1.304 -        print "\n";
   1.305 -    }
   1.306 -}
   1.307 -
   1.308 -sub lm_do
   1.309 -# Do the $_[0] command on all of the hosts 
   1.310 -{
   1.311 -    my $command = shift;
   1.312 -    my $arg = join " ", @_;
   1.313 -    my $i=1;
   1.314 -
   1.315 -    my %myenv = ( %Config, 
   1.316 -                lab =>  $arg,           
   1.317 -                center  =>  $XMLClass->{"center"},
   1.318 -                course  =>  $XMLClass->{"course"},
   1.319 -                date    =>  $XMLClass->{"date"},
   1.320 -                stopdate    =>  $XMLClass->{"stop-date"},
   1.321 -                instructor  =>  $XMLClass->{"instructor"}->{"firstname"}." ".$XMLClass->{"instructor"}->{"surname"},
   1.322 -                manager     =>  $XMLClass->{"manager"}->{"firstname"}." ".$XMLClass->{"manager"}->{"surname"},
   1.323 -                coursepath =>   $XMLCourse->{"path"},
   1.324 -            );
   1.325 -
   1.326 -    if (grep { $_ eq "PRE-$command"} keys %Scripts) {
   1.327 -        $_=$Scripts{"PRE-$command"};
   1.328 -        s/\$(\w+)/$myenv{$1}/ge;
   1.329 -        open(SHELL, "|/bin/sh -s");
   1.330 -        binmode SHELL, ":utf8";
   1.331 -        print SHELL $_;
   1.332 -        close (SHELL);
   1.333 -    }
   1.334 -
   1.335 -
   1.336 -    for my $m (sort keys %Machines) {
   1.337 -        if (!@SelectedMachines || grep $_ eq $i, @SelectedMachines) {
   1.338 -            print "$m:\n" if $Config{"show_host"} =~ /y/i;
   1.339 -
   1.340 -            %myenv = ( %myenv,
   1.341 -                host    =>  $m,
   1.342 -                ipaddress   =>  $Machines{$m}->{"ipaddress"},
   1.343 -                dirs    =>  "/root /home/".$Machines{$m}->{"user"},
   1.344 -                lablogs =>  $Config{"path_lablogs"}."/".
   1.345 -                        $XMLClass->{"course"}."/".
   1.346 -                        $XMLClass->{"date"}."/".
   1.347 -                        "$m",
   1.348 -                email   =>  $Machines{$m}->{"student"}->{"email"},
   1.349 -                company =>  $Machines{$m}->{"student"}->{"company"},
   1.350 -                name    =>  $Machines{$m}->{"name"},
   1.351 -                firstname   =>  $Machines{$m}->{"firstname"},
   1.352 -            );
   1.353 -            if (grep { $_ eq $command} keys %Scripts) {
   1.354 -                $_=$Scripts{"$command"};
   1.355 -                s/\$(\w+)/$myenv{$1}/ge;
   1.356 -                open(SHELL, "|/bin/sh -s");
   1.357 -                binmode SHELL, ":utf8";
   1.358 -                print SHELL $_;
   1.359 -                close (SHELL);
   1.360 -            }
   1.361 -            else {
   1.362 -                my $res = `ssh $Config{"ssh_user"}\@$m $command`;
   1.363 -                if ($res) {
   1.364 -                    my $count = ($res =~ s/(^)/$m: /mg);
   1.365 -                    print $res;
   1.366 -                    print "\n" if ($count > 1);
   1.367 -                }
   1.368 -            }   
   1.369 -        }   
   1.370 -        $i++;
   1.371 -    }
   1.372 -
   1.373 -    if (grep { $_ eq "POST-$command"} keys %Scripts) {
   1.374 -        $_=$Scripts{"POST-$command"};
   1.375 -        s/\$(\w+)/$myenv{$1}/ge;
   1.376 -        open(SHELL, "|/bin/sh -s");
   1.377 -        binmode SHELL, ":utf8";
   1.378 -        print SHELL $_;
   1.379 -        close (SHELL);
   1.380 -    }
   1.381 -}
   1.382 -
   1.383 -
   1.384 -
   1.385 -=cut comment
   1.386 -
   1.387 -lm report
   1.388 -
   1.389 -Построить html представление для журналов текущего класса.
   1.390 -Для построения используется скрипт l3-report.
   1.391 -
   1.392 -=cut
   1.393 -
   1.394 -sub lm_report
   1.395 -{
   1.396 -
   1.397 -    my $webdir = $Config{"path_web"};
   1.398 -    my $course=$XMLClass->{"course"};
   1.399 -    my $date=$XMLClass->{"date"};
   1.400 -    my $encoding=$XMLClass->{"charset"};
   1.401 -
   1.402 -    my $center = $XMLClass->{"center"};
   1.403 -    my $instructor = $XMLClass->{"instructor"}->{"firstname"}." ".$XMLClass->{"instructor"}->{"surname"};
   1.404 -    my $course_name = $XMLCourse->{"fullname"}[0];
   1.405 -
   1.406 -
   1.407 -    # Собственно журналы
   1.408 -
   1.409 -    for my $student (@{$XMLClass->{"student"}}) {
   1.410 -        my $user = $student->{"user"};
   1.411 -        my $hostname = $student->{"host"};
   1.412 -        my $encoding = $student->{"charset"};
   1.413 -        my $student_name = $student->{"firstname"}." ".$student->{"surname"};
   1.414 -
   1.415 -        system("mkdir -p $webdir/$date/$hostname");
   1.416 -        system("cp ".$Config{"path_share"}."/*.{ico,css} $webdir/$date/$hostname");
   1.417 -        system($Config{"l3-report"}.
   1.418 -            " --input ".$Config{"path_lablogs"}."/$course/$date/$hostname/$user".
   1.419 -            " --diffs ".$Config{"path_lablogs"}."/$course/$date/$hostname/$user ".
   1.420 -                   $Config{"path_lablogs"}."/$course/$date/$hostname/root".
   1.421 -            " --output $webdir/$date/$hostname/$user.html".
   1.422 -            " --course-name '$course_name'".
   1.423 -            " --course-code '$course'".
   1.424 -            " --course-date '$date'".
   1.425 -            " --course-center '$center'".
   1.426 -            " --course-student '$student_name'".
   1.427 -            " --course-trainer '$instructor'".
   1.428 -            " --encoding $encoding"
   1.429 -        );
   1.430 -        system($Config{"l3-report"}.
   1.431 -            " --input ".$Config{"path_lablogs"}."/$course/$date/$hostname/root".
   1.432 -            " --diffs ".$Config{"path_lablogs"}."/$course/$date/$hostname/root ".
   1.433 -            " --output $webdir/$date/$hostname/root.html".
   1.434 -            " --course-name '$course_name'".
   1.435 -            " --course-code '$course'".
   1.436 -            " --course-date '$date'".
   1.437 -            " --course-center '$center'".
   1.438 -            " --course-student '$student_name'".
   1.439 -            " --course-trainer '$instructor'".
   1.440 -            " --encoding $encoding"
   1.441 -        );
   1.442 -    }
   1.443 -
   1.444 -    # Индекс для данного класса
   1.445 -
   1.446 -    my $head;
   1.447 -
   1.448 -    $head="Журналы лабораторных работ";
   1.449 -    open(HTML, ">$webdir/$date/index.html")
   1.450 -        or die "Can't open $webdir/$date/index.html for writing";
   1.451 -    binmode HTML, ":utf8";
   1.452 -    print HTML <<HEAD;
   1.453 -    <html>
   1.454 -    <head>
   1.455 -    <meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
   1.456 -    <title>$head</title>
   1.457 -    </head>
   1.458 -    <body>
   1.459 -    <h1>$head</h1>
   1.460 -    <p>
   1.461 -    Курс: $course_name ($course)<br/>
   1.462 -    Начало: $date<br/>
   1.463 -    Учебный центр: $center <br/>
   1.464 -    Инструктор: $instructor <br/>
   1.465 -    </p>
   1.466 -    <table>
   1.467 -HEAD
   1.468 -    for my $student (@{$XMLClass->{"student"}}) {
   1.469 -        my $user = $student->{"user"};
   1.470 -        my $hostname = $student->{"host"};
   1.471 -        print HTML "<tr>\n";
   1.472 -        print HTML "<td>",$student->{"firstname"}," ",$student->{"surname"},"</td>\n";
   1.473 -        print HTML "<td>",$hostname,"</td>\n";
   1.474 -        print HTML "<td><a href=\"$hostname/$user.html\">",$user,"</td>\n";
   1.475 -        print HTML "<td><a href=\"$hostname/root.html\">","root","</td>\n";
   1.476 -        print HTML "</tr>\n";
   1.477 -    }
   1.478 -    print HTML <<TAIL;
   1.479 -    </table>
   1.480 -    </html>
   1.481 -TAIL
   1.482 -    close (HTML);
   1.483 -
   1.484 -    
   1.485 -    
   1.486 -}
   1.487 -
   1.488 -sub load_run
   1.489 -{
   1.490 -    my $runfile = $Config{"path_labmaker"}."/".$Config{"path_runfile"};
   1.491 -    open (RUN, $runfile)
   1.492 -        or return;
   1.493 -    while (<RUN>) {
   1.494 -        chomp;
   1.495 -        my ($var, $val) = split /\s+/,$_,2;
   1.496 -        $Run{$var}=$val;
   1.497 -    }
   1.498 -    close (RUN);    
   1.499 -}
   1.500 -
   1.501 -sub save_run
   1.502 -{
   1.503 -    my $runfile = $Config{"path_labmaker"}."/".$Config{"path_runfile"};
   1.504 -    open (RN, "$runfile")
   1.505 -        or die "Can't save running state to $runfile";
   1.506 -    for my $var (keys %Run) {
   1.507 -        print RN $var,"\t",$Run{$var},"\n";
   1.508 -    }
   1.509 -    close (RN); 
   1.510 -}
   1.511 -
   1.512 -sub print_log
   1.513 -{
   1.514 -    my $logfile = $Config{"path_labmaker"}."/".$Config{"path_logfile"};
   1.515 -    open (LOG, ">>$logfile")
   1.516 -        or die "Can't open logfile $logfile for writing";
   1.517 -    print LOG  @_;
   1.518 -    close (LOG);    
   1.519 -}
   1.520 -
   1.521 -
   1.522 -sub print_usage_info
   1.523 -{
   1.524 -    print "Usage:\n\n\t$0 [host-list] command\n";
   1.525 -    print <<'USAGE';
   1.526 -
   1.527 -Commands:
   1.528 -
   1.529 -    next        -- next lab
   1.530 -    prev        -- prev lab
   1.531 -    set LAB     -- set current lab to LAB
   1.532 -    start       -- start this day training
   1.533 -    stop        -- stop this day training
   1.534 -    show hosts  -- show available hosts in the class
   1.535 -    show labs   -- show available labs in the course
   1.536 -    do COMMAND  -- do specified command on the hosts of hostlist
   1.537 -    report      -- generate XML/HTML reports
   1.538 -
   1.539 -    
   1.540 -do commands:
   1.541 -    
   1.542 -    install [PROFILE] -- install profile 
   1.543 -    
   1.544 -Host list:  
   1.545 -
   1.546 -    @N      -- machine N
   1.547 -    @N1-N2      -- all of the machines from N1 to N2
   1.548 -    @N1,N2,N3   -- machine N1, N2 and N3
   1.549 -
   1.550 -    N* is numbers or domain names of the machines.
   1.551 -    
   1.552 -    If host list is not specified, 
   1.553 -    command is executed on all of the machines
   1.554 -
   1.555 -USAGE
   1.556 -}
   1.557 -
   1.558 -
     2.1 --- a/lm-install	Mon Jul 21 11:24:53 2008 +0300
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,258 +0,0 @@
     2.4 -#!/bin/sh
     2.5 -
     2.6 -# Use -d to deinstall labmaker
     2.7 -# You can specify directory list to install LabMaker as command line parameters
     2.8 -# or set it in $users_to_install variable
     2.9 -
    2.10 -# CONFIGURABLE SECTION start
    2.11 -#users_to_install="/home/your-user-here /root"
    2.12 -# CONFIGURABLE SECTION stop
    2.13 -
    2.14 -first_lab=T1
    2.15 -editors_to_install='/bin/vi /usr/bin/vi /usr/bin/vim /bin/ee /usr/bin/ee /usr/bin/pico /usr/bin/nano /usr/local/bin/vim'
    2.16 -temp_file=/tmp/lm-install-$$
    2.17 -arg=$@
    2.18 -
    2.19 -show_usage()
    2.20 -{
    2.21 -	cat << USAGE 
    2.22 -
    2.23 -$0 [-d] path...
    2.24 -
    2.25 -	* Use -d to deinstall labmaker
    2.26 -	* You can specify directory list to install LabMaker as command line parameters
    2.27 -	  or set it in \$users_to_install variable in the script
    2.28 -
    2.29 -Example:
    2.30 -
    2.31 -	Command
    2.32 -	# $0 /root /home/user
    2.33 -	installs labmaker to /root and /home/user directories 
    2.34 -
    2.35 -USAGE
    2.36 -}
    2.37 -
    2.38 -install_to_profile()
    2.39 -{
    2.40 -	profile=$1
    2.41 -	cat <<'LM_bash_profile' > $temp_file
    2.42 -# LabMaker:START
    2.43 -/usr/local/bin/l3-agent
    2.44 -# LabMaker:END
    2.45 -LM_bash_profile
    2.46 -	cat $profile \
    2.47 -		| sed '/LabMaker:START/,/LabMaker:END/ d' \
    2.48 -		>> $temp_file
    2.49 -	cat $temp_file > $profile
    2.50 -	rm $temp_file
    2.51 -}
    2.52 -
    2.53 -uninstall_from_profile()
    2.54 -{
    2.55 -	profile=$1
    2.56 -	cat $profile \
    2.57 -		| sed '/LabMaker:START/,/LabMaker:END/ d' \
    2.58 -		> $temp_file
    2.59 -	cat $temp_file > $profile
    2.60 -	rm $temp_file
    2.61 -}
    2.62 -
    2.63 -install_to_bashrc()
    2.64 -{
    2.65 -	profile=$1
    2.66 -	cat $profile \
    2.67 -		| sed '/LabMaker:START/,/LabMaker:END/ d' \
    2.68 -		> $temp_file
    2.69 -	cat <<'LM_bash_profile' >> $temp_file
    2.70 -# LabMaker:START
    2.71 -LMHOME=~/.lilalo
    2.72 -mkdir -p ${LMHOME}
    2.73 -
    2.74 -uname -a | grep -qi bsd && bsd=yes
    2.75 -flush="-f"			#linux
    2.76 -[ -n "$bsd" ] && flush="-t 0"	#freebsd
    2.77 -
    2.78 -tty=`tty` 
    2.79 -this_term=`w | grep "${tty##/dev/}" | awk '{print $8;}'`
    2.80 -# freeBSD: 
    2.81 -[ -n "$bsd" ] && this_term=`w | grep "${tty##/dev/tty}" | awk '{print $6;}'`
    2.82 -
    2.83 -
    2.84 -export PS1='\[`	
    2.85 -	a="$?";
    2.86 -	HIDDEN=$([ "$a" = 0 ] || echo -n ^"$a")$(echo -n _${UID}_)$(echo -n _$$_)$(date\
    2.87 -		+"%j$(cat ${LMHOME}/lab 2>/dev/null) %H:%M:%S");
    2.88 -	echo $HIDDEN`\033[50D\033[K\][\u@\h:\W]\$ '
    2.89 -
    2.90 -if [ -n "$this_term" ] && echo $this_term | grep -qv script
    2.91 -then	
    2.92 -	session_id=${tty##*/}-$$
    2.93 -	parent=`cat /proc/$PPID/cmdline 2> /dev/null`
    2.94 -	system=`uname -rs`
    2.95 -	login_from=`who | grep "${tty##/dev/}" | awk '{print $6;}' | tr -d '()'`
    2.96 -	#[ -n "$bsd" ] && login_from="" #FIXME!
    2.97 -	start_time=`date +%s`
    2.98 -	hostname=`hostname -f 2> /dev/null`
    2.99 -	[ -n "$bsd" ] && hostname=`hostname`
   2.100 -
   2.101 -	cat <<INFO > $LMHOME/${session_id}.info
   2.102 -<session>
   2.103 -<local_session_id>$session_id</local_session_id>
   2.104 -<hostname>$hostname</hostname>
   2.105 -<user>$USER</user>
   2.106 -<uid>$UID</uid>
   2.107 -<login_from>$login_from</login_from>
   2.108 -<tty>$tty</tty>
   2.109 -<system>$system</system>
   2.110 -<parent>$parent</parent>
   2.111 -<ppid>$PPID</ppid>
   2.112 -<pid>$$</pid>
   2.113 -<start_time>$start_time</start_time>
   2.114 -</session>
   2.115 -INFO
   2.116 -
   2.117 -	exec script $flush -q $LMHOME/${session_id}.script
   2.118 -fi
   2.119 -# LabMaker:END 
   2.120 -LM_bash_profile
   2.121 -	cat $temp_file > $profile
   2.122 -	rm $temp_file
   2.123 -}
   2.124 -
   2.125 -uninstall_from_bashrc()
   2.126 -{
   2.127 -	profile=$1
   2.128 -	cat $profile \
   2.129 -		| sed '/LabMaker:START/,/LabMaker:END/ d' \
   2.130 -		> $temp_file
   2.131 -	cat $temp_file > $profile
   2.132 -	rm $temp_file
   2.133 -}
   2.134 -
   2.135 -install_editor()
   2.136 -{
   2.137 -editor=$1
   2.138 -[ -e $editor.orig ] && cp $editor.orig $editor
   2.139 -cp $editor $editor.orig
   2.140 -cat <<'editor_wrapper' | sed "s@EDITOR@$editor@" > $editor
   2.141 -#!/bin/sh
   2.142 -
   2.143 -LMHOME=~/.lilalo
   2.144 -if [ "${1#-}" = "$1" -a -d "$LMHOME" ]
   2.145 -then
   2.146 -	LAB=`cat $LMHOME/lab`
   2.147 -	TIME="`date +%j${LAB}_%H:%M:%S`"
   2.148 -	DIR=""
   2.149 -	[ "${1#/}" = "$1" ] && DIR=$PWD/
   2.150 -	DIFFNAME=$PPID_${TIME}_`echo $DIR$1| sed s@_@__@ | sed 's@/@_@g'`.diff
   2.151 -	tmp="/tmp/lm-saved-$$"
   2.152 -	touch $1
   2.153 -	cp -- "$1" $tmp 2> /dev/null
   2.154 -	EDITOR.orig "$@" || ERR=1
   2.155 -	diff $tmp $1 > $LMHOME/$DIFFNAME 2> /dev/null
   2.156 -	rm $tmp 2> /dev/null
   2.157 -	if [ "$ERR" = 1 ]
   2.158 -	then
   2.159 -		false
   2.160 -	else
   2.161 -		true
   2.162 -	fi	
   2.163 -else
   2.164 -	exec EDITOR.orig "$@"
   2.165 -fi
   2.166 -editor_wrapper
   2.167 -
   2.168 -}
   2.169 -
   2.170 -
   2.171 -uninstall_editor()
   2.172 -{
   2.173 -	editor=$1
   2.174 -	[ -e $editor.orig ] && mv $editor.orig $editor
   2.175 -}
   2.176 -
   2.177 -if [ "$1" != "-d" ] 
   2.178 -then 
   2.179 -	# INSTALLING LM
   2.180 -	if [ $# -gt 0 ] 
   2.181 -	then
   2.182 -		users_to_install="$*"
   2.183 -	fi
   2.184 -
   2.185 -	if [ -z "$users_to_install" ]
   2.186 -	then 
   2.187 -		show_usage
   2.188 -		exit
   2.189 -	fi	
   2.190 -
   2.191 -	for home in $users_to_install
   2.192 -	do 
   2.193 -		# fix this!
   2.194 -		user=${home%/} 
   2.195 -		user=${user##*/}
   2.196 -		mkdir -p $home/.lilalo
   2.197 -		echo $first_lab > $home/.lilalo/lab
   2.198 -		chown -R $user $home/.lilalo
   2.199 -
   2.200 -		#if [ ! -e $home/.bash_profile ] 
   2.201 -		#then
   2.202 -		#	echo '. ~/.bashrc' >> ~/.bash_profile
   2.203 -		#fi
   2.204 -		#[ -e $home/.bash_profile ] \
   2.205 -		#	&& install_to_profile $home/.bash_profile \
   2.206 -		#	&& echo LabMaker is installed to $home/.bash_profile
   2.207 -
   2.208 -		echo Don\'t forget to check .bash_profile for .bashrc call
   2.209 -
   2.210 -		[ -e $home/.bash_profile ] && install_to_profile $home/.bash_profile \
   2.211 -			&& install_to_profile $home/.bash_profile \
   2.212 -			&& echo LabMaker is installed to $home/.bash_profile
   2.213 -
   2.214 -		touch $home/.bashrc
   2.215 -		[ -e $home/.bashrc ] && install_to_bashrc $home/.bashrc \
   2.216 -			&& install_to_bashrc $home/.bashrc \
   2.217 -			&& echo LabMaker is installed to $home/.bashrc
   2.218 -	done
   2.219 -
   2.220 -	for editor in $editors_to_install
   2.221 -	do
   2.222 -		[ -e $editor ] \
   2.223 -			&& install_editor $editor \
   2.224 -			&& echo LabMaker is installed to $editor
   2.225 -	done
   2.226 -else
   2.227 -# UNINSTALLING LM
   2.228 -	shift
   2.229 -	users_to_install="$*"
   2.230 -	for user in $users_to_install
   2.231 -	do 
   2.232 -		home=$user		
   2.233 -		mkdir -p $home/.lilalo
   2.234 -		echo $first_lab > $home/.lilalo/lab
   2.235 -		chown -R ${user##*/} $home/.lilalo
   2.236 -
   2.237 -		#if [ ! -e $home/.bash_profile ] 
   2.238 -		#then
   2.239 -		#	echo '. ~/.bashrc' >> ~/.bash_profile
   2.240 -		#fi
   2.241 -		#[ -e $home/.bash_profile ] \
   2.242 -		#	&& uninstall_from_profile $home/.bash_profile \
   2.243 -		#	&& echo LabMaker is uninstalled from $home/.bash_profile
   2.244 -
   2.245 -		[ -e $home/.profile ] && uninstall_from_profile $home/.profile \
   2.246 -			&& uninstall_from_profile $home/.profile \
   2.247 -			&& echo LabMaker is uninstalled from $home/.profile
   2.248 -
   2.249 -		touch $home/.bashrc
   2.250 -		[ -e $home/.bashrc ] && uninstall_from_bashrc $home/.bashrc \
   2.251 -			&& uninstall_from_bashrc $home/.bashrc \
   2.252 -			&& echo LabMaker is uninstalled from $home/.bashrc
   2.253 -	done
   2.254 -
   2.255 -	for editor in $editors_to_install
   2.256 -	do
   2.257 -		[ -e $editor ] \
   2.258 -			&& uninstall_editor $editor \
   2.259 -			&& echo LabMaker is uninstalled from $editor
   2.260 -	done
   2.261 -fi	
     3.1 --- a/lm-report	Mon Jul 21 11:24:53 2008 +0300
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,1186 +0,0 @@
     3.4 -#!/usr/bin/perl -w
     3.5 -
     3.6 -#
     3.7 -# (c) Igor Chubin, imchubin@mail.ru, 2004-2005
     3.8 -#
     3.9 -
    3.10 -use strict;
    3.11 -use Getopt::Long;
    3.12 -use Term::VT102;
    3.13 -use Text::Iconv;
    3.14 -use Data::Dumper;
    3.15 -
    3.16 -our $Config_File = "labmaker.conf";
    3.17 -our %Config = (
    3.18 -		"skip_empty" 			=> 	"yes",
    3.19 -		"skip_interrupted" 		=>	"no",
    3.20 -		"skip_wrong" 			=>	"no",
    3.21 -		"editors"			=>	["vi", "pico", "ee", "vim"],
    3.22 -		"pagers"			=>	["more", "less", "zmore", "zless", "info", 
    3.23 -							"man", "mc", "trafshow", "screen", "cfdisk",
    3.24 -							"trafshow-bsd", "yes", "lynx", "links", "centericq"
    3.25 -							],
    3.26 -		"terminal"			=>	["mc"],
    3.27 -		"suppress_editors"		=>	"yes",
    3.28 -		"suppress_pagers"		=>	"yes",
    3.29 -		"suppress_terminal"		=>	"yes",
    3.30 -
    3.31 -		"terminal_width"		=> 	100,
    3.32 -		"terminal_height"		=> 	100,
    3.33 -		"verbose"			=>	"yes",
    3.34 -
    3.35 -		"head_lines"			=> 	5,
    3.36 -		"tail_lines"			=>	5,
    3.37 -		"skip_text"			=>	"...",
    3.38 -		"show_time"			=>	"yes",
    3.39 -		"show_diffs"			=>	"yes",
    3.40 -		"show_comments"			=>	"yes",
    3.41 -
    3.42 -		"input"				=>	"/root/.labmaker",
    3.43 -		"diffs"				=>	"",
    3.44 -		"input_mask"			=>	"*.script",
    3.45 -		"encoding"			=> 	"utf-8",
    3.46 -
    3.47 -		"output"			=>	"/var/www/lm/reportINDEX.html",
    3.48 -		#"output"			=>	"report.xml",
    3.49 -		"output_mask"			=>	"INDEX",
    3.50 -		"output_format"			=>	"html",
    3.51 -
    3.52 -		"signature"			=>	"#lm:",
    3.53 -		"from"				=>	"",
    3.54 -		"to"				=>	"",
    3.55 -		"lab"				=>	"",
    3.56 -		"keywords"			=>	"linux command",
    3.57 -		"files_keywords"		=>	"linux file",
    3.58 -		
    3.59 -		comment_width			=>	"300",
    3.60 -		time_width			=>	"60",
    3.61 -
    3.62 -		"course-name" => "", 
    3.63 -		"course-code" => "", 
    3.64 -		"course-date" => "", 
    3.65 -		"course-center" => "", 
    3.66 -		"course-trainer" => "", 
    3.67 -		"course-student" => "", 
    3.68 -
    3.69 -		);
    3.70 -
    3.71 -our @Command_Lines;
    3.72 -our @Command_Lines_Index;
    3.73 -our @Diffs;
    3.74 -
    3.75 -our %Commands_Stat;		# Statistics about commands usage
    3.76 -our %Files_Stat;		# Statistics about commands usage
    3.77 -
    3.78 -our %Search_Machines = (
    3.79 -		"google" => 	{ 	"query" => 	"http://www.google.com/search?q=" ,
    3.80 -					"icon" 	=> 	"google.ico" },
    3.81 -		"freebsd" => 	{ 	"query" => 	"http://www.freebsd.org/cgi/man.cgi?query=",
    3.82 -					"icon"	=>	"freebsd.ico" },
    3.83 -		"linux"  => 	{ 	"query" => 	"http://man.he.net/?topic=",
    3.84 -					"icon"	=>	"linux.ico"},
    3.85 -		"opennet"  => 	{ 	"query" => 	"http://www.opennet.ru/search.shtml?words=",
    3.86 -					"icon"	=>	"opennet.ico"},
    3.87 -		"local" => 	{ 	"query" => 	"http://www.freebsd.org/cgi/man.cgi?query=",
    3.88 -					"icon"	=>	"freebsd.ico" },
    3.89 -
    3.90 -	);
    3.91 -
    3.92 -our %Elements_Visibility = (
    3.93 -		"note"		=>	"замечания",
    3.94 -		"diff"		=>	"редактор",
    3.95 -		"time"		=>	"время",
    3.96 -		"ttychange" 	=>	"терминал",
    3.97 -		"wrong_output wrong_cline wrong_root_output wrong_root_cline" 
    3.98 -				=>	"команды с ошибками",
    3.99 -		"interrupted_output interrupted_cline interrupted_root_output interrupted_root_cline" 
   3.100 -				=>	"прерванные команды",
   3.101 -		"tab_completion_output tab_completion_cline"	
   3.102 -				=> 	"продолжение с помощью tab"
   3.103 -);
   3.104 -
   3.105 -sub init_variables;
   3.106 -our $Html_Help;
   3.107 -our $Html_About;
   3.108 -
   3.109 -
   3.110 -sub load_diff_files
   3.111 -{
   3.112 -	my @pathes = @_;
   3.113 -	
   3.114 -	for my $path (@pathes) {
   3.115 -		my $template = "*.diff";
   3.116 -		my @files = <$path/$template>;
   3.117 -		my $i=0;
   3.118 -		for my $file (@files) {
   3.119 -			my %diff;
   3.120 -			
   3.121 -			$diff{"path"}=$path;
   3.122 -			$diff{"uid"}="SET THIS";
   3.123 -
   3.124 -# Сейчас UID определяется из названия каталога
   3.125 -# откуда берутся diff-файлы
   3.126 -# Это неправильно
   3.127 -#
   3.128 -# ВАРИАНТ:
   3.129 -# К файлам жураналам должны прилагаться ситемны файлы, 
   3.130 -# мз которых и будет определяться соответствие 
   3.131 -# имён пользователей их uid'ам
   3.132 -#
   3.133 -			$diff{"uid"} = 0 if $path =~ m@/root/@;	
   3.134 -			
   3.135 -			$diff{"bind_to"}="";
   3.136 -			$diff{"time_range"}=-1;
   3.137 -		
   3.138 -			next if not $file=~m@/(D?[0-9][0-9]?[0-9]?)[^/]*?([0-9]*):([0-9]*):?([0-9]*)@;
   3.139 -			$diff{"day"}=$1 || "";
   3.140 -			$diff{"hour"}=$2;
   3.141 -			$diff{"min"}=$3;
   3.142 -			$diff{"sec"}=$4 || 0;
   3.143 -			
   3.144 -			$diff{"index"}=$i;
   3.145 -
   3.146 -			print "diff loaded: $diff{day} $diff{hour}:$diff{min}:$diff{sec}\n";
   3.147 -			
   3.148 -			local $/;
   3.149 -			open (F, "$file")
   3.150 -				or return "Can't open file $file ($_[0]) for reading";
   3.151 -			my $text = <F>;
   3.152 -			if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i) {
   3.153 -				my $converter = Text::Iconv->new($Config{"encoding"}, "utf-8");
   3.154 -				$text = $converter->convert($text);
   3.155 -			}
   3.156 -			close(F);	
   3.157 -			$diff{"text"}=$text;
   3.158 -			#print "$file loaded ($diff{day})\n";
   3.159 -
   3.160 -			push @Diffs, \%diff;
   3.161 -			$i++;
   3.162 -		}
   3.163 -	}	
   3.164 -}
   3.165 -
   3.166 -
   3.167 -sub bind_diff
   3.168 -{
   3.169 -#	my $path = shift;
   3.170 -#	my $pid = shift;
   3.171 -#	my $day = shift;
   3.172 -#	my $lab = shift;
   3.173 -
   3.174 -	print "Trying to bind diff...\n";
   3.175 -
   3.176 -	my $cl = shift;
   3.177 -	my $hour = $cl->{"hour"};
   3.178 -	my $min = $cl->{"min"};
   3.179 -	my $sec = $cl->{"sec"};
   3.180 -
   3.181 -	my $min_dt = 10000;
   3.182 -
   3.183 -	for my $diff (@Diffs) {
   3.184 -			# Check here date, time and user
   3.185 -			next if ($diff->{"day"} && $cl->{"day"} && ($cl->{"day"} ne $diff->{"day"}));
   3.186 -			#next if (!$diff->{"uid"} && $cl->{"euid"} != $diff->{"uid"});
   3.187 -			
   3.188 -			my $dt=($diff->{"hour"}-$hour)*3600 +($diff->{"min"}-$min)*60 + ($diff->{"sec"}-$sec);
   3.189 -			if ($dt >0  && $dt < $min_dt && ($diff->{"time_range"} <0 || $dt < $diff->{"time_range"})) {
   3.190 -				print "Approppriate diff found: dt=$dt\n";
   3.191 -				if ($diff->{"bind_to"}) {
   3.192 -					undef $diff->{"bind_to"}->{"diff"};
   3.193 -				};
   3.194 -				$diff->{"time_range"}=$dt;
   3.195 -				$diff->{"bind_to"}=$cl;
   3.196 -
   3.197 -				$cl->{"diff"} = $diff->{"index"};
   3.198 -				$min_dt = $dt;	
   3.199 -			}
   3.200 -		
   3.201 -	}
   3.202 -}
   3.203 -
   3.204 -
   3.205 -sub extract_from_cline
   3.206 -# Разобрать командную строку $_[1] и возвратить хэш, содержащий 
   3.207 -# номер первого появление команды в строке:
   3.208 -# 	команда => первая позиция
   3.209 -{
   3.210 -	my $what = $_[0];
   3.211 -	my $cline = $_[1];
   3.212 -	my @lists = split /\;/, $cline;
   3.213 -	
   3.214 -	
   3.215 -	my @commands = ();
   3.216 -	for my $list (@lists) {
   3.217 -		push @commands, split /\|/, $list;
   3.218 -	}
   3.219 -
   3.220 -	my %commands;
   3.221 -	my %files;
   3.222 -	my $i=0;
   3.223 -	for my $command (@commands) {
   3.224 -		$command =~ /\s*(\S+)\s*(.*)/;
   3.225 -		if ($1 && $1 eq "sudo" ) {
   3.226 -			$commands{"$1"}=$i++;
   3.227 -			$command =~ s/\s*sudo\s+//;
   3.228 -		}
   3.229 -		$command =~ /\s*(\S+)\s*(.*)/;
   3.230 -		if ($1 && !defined $commands{"$1"}) {
   3.231 -				$commands{"$1"}=$i++;
   3.232 -		};	
   3.233 -		if ($2) {
   3.234 -			my $args = $2;
   3.235 -			my @args = split (/\s+/, $args);
   3.236 -			for my $a (@args) {
   3.237 -				$files{"$a"}=$i++
   3.238 -					if !defined $files{"$a"};
   3.239 -			};	
   3.240 -
   3.241 -				
   3.242 -		}
   3.243 -	}
   3.244 -
   3.245 -	if ($what eq "commands") {
   3.246 -		return %commands;
   3.247 -	} else {
   3.248 -		return %files;
   3.249 -	}
   3.250 -	
   3.251 -}
   3.252 -
   3.253 -sub load_command_lines
   3.254 -{
   3.255 -	my $lab_scripts_path = $_[0];
   3.256 -	my $lab_scripts_mask = $_[1];
   3.257 -
   3.258 -	my $cline_re_base = qq'
   3.259 -			(?:\\^?([0-9]*C?))					# exitcode
   3.260 -			(?:_([0-9]+)_)?				# uid
   3.261 -			(?:_([0-9]+)_)				# pid
   3.262 -			(...?)					# day
   3.263 -			(.?.?)					# lab
   3.264 -			\\s					# space separator
   3.265 -			([0-9][0-9]):([0-9][0-9]):([0-9][0-9])	# time
   3.266 -			.\\[50D.\\[K				# killing symbols
   3.267 -			(.*?([\$\#]\\s?))			# prompt
   3.268 -			(.*)					# command line
   3.269 -			';
   3.270 -	#my $cline_re = qr/$cline_re_base(?:$cline_re_base|$)/x;
   3.271 -	#my $cline_re = qr/(?:$cline_re_base)*$cline_re_base$/x;
   3.272 -	my $cline_re = qr/$cline_re_base/sx;
   3.273 -	my $cline_re1 = qr/$cline_re_base\x0D/sx;
   3.274 -	my $cline_re2 = qr/$cline_re_base$/sx;
   3.275 -
   3.276 -	my $vt = Term::VT102->new (	'cols' => $Config{"terminal_width"}, 
   3.277 -					'rows' => $Config{"terminal_height"});
   3.278 -	my $cline_vt = Term::VT102->new ('cols' => $Config{"terminal_width"}, 
   3.279 -					'rows' => $Config{"terminal_height"});
   3.280 -
   3.281 -	my $converter = Text::Iconv->new($Config{"encoding"}, "utf-8")
   3.282 -		if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i);
   3.283 -		
   3.284 -	print "Loading lm-scripts...\n" if $Config{"verbose"} =~ /y/;
   3.285 -
   3.286 -	my @lab_scripts = <$lab_scripts_path/$lab_scripts_mask>;
   3.287 -	my $file;
   3.288 -	my $files_number = $#lab_scripts;
   3.289 -	my $ii = 0;
   3.290 -	my $skip_info;
   3.291 -
   3.292 -	my $commandlines_loaded =0;
   3.293 -	my $commandlines_processed =0;
   3.294 -
   3.295 -	for $file (@lab_scripts){
   3.296 -		#printf "\t%i %3.2f\n", $ii, (100*$ii++/$files_number) if $Config{"verbose"} =~ /y/;
   3.297 -
   3.298 -		open (FILE, "$file");
   3.299 -		binmode FILE;
   3.300 -		$file =~ m@.*/(.*?)-.*@;
   3.301 -		
   3.302 -		my $tty = $1;
   3.303 -		my $first_pass = 1;
   3.304 -		my %cl;
   3.305 -		my $last_output_length=0;
   3.306 -		while (<FILE>) {
   3.307 -			$commandlines_processed++;
   3.308 -				# time
   3.309 -
   3.310 -			if (/[0-9][0-9]:[0-9][0-9]:[0-9][0-9].\[[0-9][0-9]D.\[K/ && m/$cline_re/) {
   3.311 -				s/.*\x0d(?!\x0a)//;
   3.312 -		#		print "!!!",$_,"!!!\n";
   3.313 -			#	next;
   3.314 -			#	while (m/$cline_re1/gs) {
   3.315 -			#	}
   3.316 -				m/$cline_re2/gs;
   3.317 -
   3.318 -				$commandlines_loaded++;
   3.319 -				$last_output_length=0;
   3.320 -
   3.321 -				# Previous command
   3.322 -				my %last_cl = %cl;
   3.323 -				my $err = $1 || "";
   3.324 -
   3.325 -
   3.326 -=cut 
   3.327 -
   3.328 -ТАБЛИЦА КОМАНД
   3.329 -
   3.330 -	uid
   3.331 -		Идентификатор пользователя
   3.332 -	
   3.333 -	tty 
   3.334 -		Идентификатор терминала, на котором была вызвана команда
   3.335 -
   3.336 -	pid
   3.337 -		PID-процесса командного интерпретатора, 
   3.338 -		в котором была вызвана команда
   3.339 -	
   3.340 -	lab 
   3.341 -		лабораторная работа, к которой относится команда.
   3.342 -		Идентификатор текущей лабораторной работы 
   3.343 -		хранится в файле ~/.labmaker/lab
   3.344 -
   3.345 -	pwd (!)
   3.346 -		текущий каталог, из которого была вызвана команда
   3.347 -
   3.348 -	day
   3.349 -		время вызова, день
   3.350 -		В действительности здесь хранится не время вызова команды,
   3.351 -		а с момента появления приглашения командного интерпретатора
   3.352 -		для ввода команды
   3.353 -		
   3.354 -	
   3.355 -	hour
   3.356 -		время вызова, час
   3.357 -	
   3.358 -	min
   3.359 -		время вызова, минута
   3.360 -	
   3.361 -	sec
   3.362 -		время вызова, секунда
   3.363 -	
   3.364 -	time (!)
   3.365 -		время вызова команды в Unix-формате.
   3.366 -		Предпочтительнее использовать этот формат чем hour:min:sec,
   3.367 -		использовавшийся в Labmaker
   3.368 -	
   3.369 -	fullprompt
   3.370 -		Приглашение командной строки
   3.371 -	
   3.372 -	prompt
   3.373 -		Сокращённое приглашение командной строки
   3.374 -
   3.375 -	cline 
   3.376 -		Командная строка
   3.377 -	
   3.378 -	output
   3.379 -		Результат выполнения команды
   3.380 -	
   3.381 -	diff
   3.382 -		Указатель на ассоциированный с командой diff
   3.383 -	
   3.384 -	note (!)
   3.385 -		Текстовый комментарий к команде.
   3.386 -		Может генерироваться из самого лога с помощью команд
   3.387 -			#^ Комментарий  
   3.388 -			#v Комментарий
   3.389 -		в том случае, если для комментирования достаточно одной строки,
   3.390 -		или с помощью команд
   3.391 -			cat > /dev/null #^ Заголовок
   3.392 -			Текст
   3.393 -			^D
   3.394 -		в том случае, если комментарий развёрнутый.
   3.395 -		В последнем случае комментарий может содержать 
   3.396 -		заголовок, абзацы и несложное форматирование.
   3.397 -
   3.398 -		Символ ^ или v после знака комментария # обозначает,
   3.399 -		к какой команде относится комментарий:
   3.400 -		к предыдущей (^) или последующей (v)
   3.401 -
   3.402 -	err 
   3.403 -		Код завершения командной строки
   3.404 -	
   3.405 -	histnum (!)
   3.406 -		Номер команды в истории командного интерпретатора
   3.407 -	
   3.408 -	status (!)
   3.409 -		Является ли данная команда вызванной (r), запомненной (s)
   3.410 -		или это подсказка completion (c).
   3.411 -		
   3.412 -		Команды, которые были вызваны и обработаны интерпретатором
   3.413 -		имеют состояние "r". К таким командам относится большинство 
   3.414 -		команд вводимых в интерпретатор.
   3.415 -
   3.416 -		Если команда набрана, но вызывать её по какой-либо причине
   3.417 -		не хочется (например, команда может быть не полной, вредоносной
   3.418 -		или просто бессмысленной в текущих условиях),
   3.419 -		её можно сбросить с помощью комбинации клавиш Ctrl-C
   3.420 -		(не путайте с прерыванием работающей команды! здесь она даже
   3.421 -		не запускается!).
   3.422 -		В таком случае она не выполняется, но попадает в журнал
   3.423 -		со статусом "s".
   3.424 -		
   3.425 -		Если команда появилась в журнале благодаря автопроолжению 
   3.426 -		-- когда было показано несколько вариантов --
   3.427 -		она имеет статус "c".
   3.428 -	
   3.429 -	euid
   3.430 -		Идентификатор пользователя от имени которого будет 
   3.431 -		выполняться команда.
   3.432 -		Может отличаться от реального uid в том случае,
   3.433 -		если вызывается с помощью sudo
   3.434 -
   3.435 -	
   3.436 -	version (!)
   3.437 -		Версия lilalo-prompt использовавшаяся при записи
   3.438 -		команды.
   3.439 -
   3.440 -		0 - версия использовавшая в labmaker.
   3.441 -			Отсутствует информация о текущем каталоге и номере в истории. 
   3.442 -			Информация о версии также не указана в приглашении.
   3.443 -			
   3.444 -		
   3.445 -		1 - версия использующаяся в lilalo
   3.446 -		
   3.447 -	raw_file (*)
   3.448 -		Имя файла, в котором находится бинарное представление журнала.
   3.449 -		Может содержать ключевое слово HERE, 
   3.450 -		обозначающее что бинарное представление хранится
   3.451 -		непосредственно в базе данных в атрибуте raw_data
   3.452 -
   3.453 -	raw_start (*)
   3.454 -		Начало блока командной строки в файле бинарного представления
   3.455 -	
   3.456 -	raw_end (*)
   3.457 -		Конец блока командной строки в файле бинарного представления
   3.458 -
   3.459 -	raw_cline (*)
   3.460 -		Необработанная командная строка в бинарном виде
   3.461 -	
   3.462 -	raw_data (*)
   3.463 -		Бинарное представление команды и результатов её выполнения
   3.464 -
   3.465 -
   3.466 -
   3.467 -	
   3.468 -ТАБЛИЦА SESSION
   3.469 -	
   3.470 -	Информация о сеансах
   3.471 -
   3.472 -
   3.473 -
   3.474 -
   3.475 -=cut
   3.476 -
   3.477 -				# Parse new command 
   3.478 -				$cl{"uid"} = $2;
   3.479 -				$cl{"euid"} = $cl{"uid"};	# Если в команде обнаружится sudo, euid поменяем на 0
   3.480 -				$cl{"pid"} = $3;
   3.481 -				$cl{"day"} = $4;
   3.482 -				$cl{"lab"} = $5;
   3.483 -				$cl{"hour"} = $6;
   3.484 -				$cl{"min"} = $7;
   3.485 -				$cl{"sec"} = $8;
   3.486 -				$cl{"fullprompt"} = $9;
   3.487 -				$cl{"prompt"} = $10;
   3.488 -				$cl{"raw_cline"} = $11;	
   3.489 -
   3.490 -				$cl{"err"} = 0;
   3.491 -				$cl{"output"} = "";
   3.492 -				$cl{"tty"} = $tty;
   3.493 -
   3.494 -				$cline_vt->process($cl{"raw_cline"}."\n");
   3.495 -				$cl{"cline"} = $cline_vt->row_plaintext (1);
   3.496 -				$cl{"cline"} =~ s/\s*$//;
   3.497 -				$cline_vt->reset();
   3.498 -
   3.499 -				my %commands = extract_from_cline("commands", $cl{"cline"});
   3.500 -				$cl{"euid"}=0 if defined $commands{"sudo"};
   3.501 -				my @comms = sort { $commands{$a} cmp $commands{$b} } keys %commands; 
   3.502 -				$cl{"last_command"} = $comms[$#comms] || ""; 
   3.503 -		
   3.504 -				if (
   3.505 -				$Config{"suppress_editors"} =~ /^y/i 
   3.506 -					&& grep ($_ eq $cl{"last_command"}, @{$Config{"editors"}}) ||
   3.507 -				$Config{"suppress_pagers"}  =~ /^y/i 
   3.508 -					&& grep ($_ eq $cl{"last_command"}, @{$Config{"pagers"}}) ||
   3.509 -				$Config{"suppress_terminal"}=~ /^y/i 
   3.510 -					&& grep ($_ eq $cl{"last_command"}, @{$Config{"terminal"}})
   3.511 -				) {
   3.512 -					$cl{"suppress_output"} = "1";
   3.513 -				}
   3.514 -				else {
   3.515 -					$cl{"suppress_output"} = "0";
   3.516 -					
   3.517 -				}
   3.518 -				$skip_info = 0;
   3.519 -
   3.520 -
   3.521 -				print " ",$cl{"last_command"};
   3.522 -
   3.523 -				# Processing previous command line
   3.524 -				if ($first_pass) {
   3.525 -					$first_pass = 0;
   3.526 -					next;
   3.527 -				}
   3.528 -
   3.529 -				# Error code
   3.530 -				$last_cl{"err"}=$err;
   3.531 -				$last_cl{"err"}=130 if $err eq "^C";
   3.532 -
   3.533 -				if (grep ($_ eq $last_cl{"last_command"}, @{$Config{"editors"}})) {
   3.534 -					bind_diff(\%last_cl);
   3.535 -				}
   3.536 -
   3.537 -				# Output
   3.538 -				if (!$last_cl{"suppress_output"} || $last_cl{"err"}) {
   3.539 -					for (my $i=0; $i<$Config{"terminal_height"}; $i++) {
   3.540 -						my $line= $vt->row_plaintext($i);
   3.541 -						next if !defined ($line) || $line =~ /^\s*$/;
   3.542 -						$line =~ s/\s*$//;
   3.543 -						$last_cl{"output"} .= $line."\n";
   3.544 -					}
   3.545 -				}
   3.546 -				else {
   3.547 -					$last_cl{"output"}= "";
   3.548 -				}
   3.549 -
   3.550 -				$vt->reset();
   3.551 -
   3.552 -
   3.553 -				# Classifying the command line
   3.554 -
   3.555 -
   3.556 -				# Save 
   3.557 -				if (!$Config{"lab"} || $cl{"lab"} eq $Config{"lab"}) {
   3.558 -					# Changing encoding 
   3.559 -					for (keys %last_cl) {
   3.560 -						$last_cl{$_} = $converter->convert($last_cl{$_})
   3.561 -							if ($Config{"encoding"} && 
   3.562 -							$Config{"encoding"} !~ /^utf-8$/i);
   3.563 -					}
   3.564 -					push @Command_Lines, \%last_cl;	
   3.565 -				}	
   3.566 -				next;
   3.567 -			}
   3.568 -			$last_output_length+=length($_);
   3.569 -			#if (!$cl{"suppress_output"} || $last_output_length < 5000) {
   3.570 -			if ($last_output_length < 50000) {
   3.571 -				#print "(",length($_),")" if (length($_) > 2000) ;
   3.572 -				$vt->process("$_"."\n") 
   3.573 -			}
   3.574 -			else
   3.575 -			{
   3.576 -				if (!$skip_info) {
   3.577 -					print "($cl{last_command})";
   3.578 -					$skip_info = 1;
   3.579 -				}
   3.580 -			}
   3.581 -		}	
   3.582 -		close(FILE);
   3.583 -
   3.584 -	}
   3.585 -	if ($Config{"verbose"} =~ /y/) {
   3.586 -		print "...finished." ;
   3.587 -		print "Lines loaded: $commandlines_processed\n";
   3.588 -		print "Command lines: $commandlines_loaded\n";
   3.589 -	}
   3.590 -}
   3.591 -
   3.592 -sub search_by
   3.593 -{
   3.594 -	my $sm = shift;
   3.595 -	my $topic = shift;
   3.596 -	$topic =~ s/ /+/;
   3.597 -	
   3.598 -	return "<a href='".	$Search_Machines{$sm}->{"query"}."$topic'><img width='16' height='16' src='".
   3.599 -				$Search_Machines{$sm}->{"icon"}."' border='0'/></a>";
   3.600 -}
   3.601 -
   3.602 -sub make_comment
   3.603 -{
   3.604 -	my $commands = $_[0];
   3.605 -	my $files = $_[1];
   3.606 -	chomp $commands;
   3.607 -	chomp $files;
   3.608 -	return if (!$commands && !$files);
   3.609 -
   3.610 -	my $comment=""; 
   3.611 -
   3.612 -	# Commands
   3.613 -	for my $command (split /\s+/,$commands) {
   3.614 -		$command =~ s/'//g;
   3.615 -		my $description="";
   3.616 -		eval { $description=`mywi-client '$command'`; } ;
   3.617 -		$description = join ("<br>\n", grep(/\([18]\)/, split(/\n/, $description)));
   3.618 -		$description =~ s/.*?-//;
   3.619 -		next if $description =~ /^\s*$/; 
   3.620 -		
   3.621 -		my $query=$command." ".$Config{"keywords"};
   3.622 -		$query =~ s/\ /+/g;
   3.623 -		my $search= 	search_by("opennet",$query).
   3.624 -				search_by("local",$command).
   3.625 -				search_by("google",$query);
   3.626 -
   3.627 -		$comment .=     "<tr><td class='note_title'>$command</td>".
   3.628 -				"<td class='note_search'>$search</td>".
   3.629 -				"</tr><tr><td width='100%' colspan='2' class='note_text'>".
   3.630 -				"$description</td></tr><tr/>";
   3.631 -	}
   3.632 -	
   3.633 -	# Files
   3.634 -	for my $file (split /\s+/,$files) {
   3.635 -		$file =~ s@.*/@@;
   3.636 -		$file =~ s/'//g;
   3.637 -		next if $file =~ /^\s*$/;
   3.638 -		next if $file =~ /^-/;
   3.639 -		
   3.640 -		my $description=`mywi '$file'`;
   3.641 -		$description = join ("<br>\n", grep(/\(5\)/, split(/\n/, $description)));
   3.642 -		next if $description =~ /^\s*$/; 
   3.643 -
   3.644 -		my $query=$file." ".$Config{"files_keywords"};
   3.645 -		$query =~ s/\ /+/g;
   3.646 -		my $search= 	search_by("opennet",$query).
   3.647 -				search_by("local",$file).
   3.648 -				search_by("google",$query);
   3.649 -
   3.650 -		$comment .=     "<tr><td class='note_title'>$file</td>".
   3.651 -				"<td class='note_search'>$search</td>".
   3.652 -				"</tr><tr><td width='100%' colspan='2' class='note_text'>".
   3.653 -				"$description</td></tr><tr/>";
   3.654 -	}
   3.655 -
   3.656 -
   3.657 -	return $comment;
   3.658 -}
   3.659 -
   3.660 -sub printq
   3.661 -{
   3.662 -	my $TO = shift;
   3.663 -	my $text = join "", @_;
   3.664 -	$text =~ s/&/&amp;/g;
   3.665 -	$text =~ s/</&lt;/g;
   3.666 -	$text =~ s/>/&gt;/g;
   3.667 -	print $TO $text;
   3.668 -}
   3.669 -
   3.670 -
   3.671 -sub sort_command_lines
   3.672 -{
   3.673 -	print "Sorting command lines...\n" if $Config{"verbose"} =~ /y/;
   3.674 -
   3.675 -	# Sort Command_Lines
   3.676 -	# Write Command_Lines to Command_Lines_Index
   3.677 -
   3.678 -	my @index;
   3.679 -	for (my $i=0;$i<=$#Command_Lines;$i++) {
   3.680 -		$index[$i]=$i;
   3.681 -	}
   3.682 -
   3.683 -	@Command_Lines_Index = sort {
   3.684 -		$Command_Lines[$index[$a]]->{"day"} cmp $Command_Lines[$index[$b]]->{"day"} ||
   3.685 -		$Command_Lines[$index[$a]]->{"hour"} <=> $Command_Lines[$index[$b]]->{"hour"} ||
   3.686 -		$Command_Lines[$index[$a]]->{"min"} <=> $Command_Lines[$index[$b]]->{"min"} ||
   3.687 -		$Command_Lines[$index[$a]]->{"sec"} <=> $Command_Lines[$index[$b]]->{"sec"}
   3.688 -	} @index;
   3.689 -
   3.690 -	print "...finished\n" if $Config{"verbose"} =~ /y/;
   3.691 -
   3.692 -}
   3.693 -
   3.694 -sub process_command_lines
   3.695 -{
   3.696 -	my $lab_scripts_path = $_[0];
   3.697 -	
   3.698 -	for my $i (@Command_Lines_Index) {
   3.699 -
   3.700 -		my $cl = \$Command_Lines[$i];
   3.701 -		@{${$cl}->{"new_commands"}} =();
   3.702 -		@{${$cl}->{"new_files"}} =();
   3.703 -		$$cl->{"class"} = ""; 
   3.704 -
   3.705 -		if ($$cl->{"err"}) {
   3.706 -			$$cl->{"class"}="wrong";
   3.707 -			$$cl->{"class"}="interrupted"
   3.708 -				if ($$cl->{"err"} eq 130);
   3.709 -		}	
   3.710 -		if (!$$cl->{"euid"}) {
   3.711 -			$$cl->{"class"}.="_root";
   3.712 -		}
   3.713 -		
   3.714 -#tab#		my @tab_words=split /\s+/, $$cl->{"output"};
   3.715 -#tab#		my $last_word= $$cl->{"cline"} =~ /(\S*)$/;
   3.716 -#tab#		$last_word =~ s@.*/@@;
   3.717 -#tab#		my $this_is_tab=1;
   3.718 -#tab#
   3.719 -#tab#		if ($last_word && @tab_words >2) {
   3.720 -#tab#			for my $tab_words (@tab_words) {
   3.721 -#tab#				if ($tab_words !~ /^$last_word/) {
   3.722 -#tab#					$this_is_tab=0;
   3.723 -#tab#					last;
   3.724 -#tab#				}
   3.725 -#tab#			}
   3.726 -#tab#		}	
   3.727 -#tab#		$$cl->{"class"}="tab" if $this_is_tab;
   3.728 -		
   3.729 -
   3.730 -		if ( !$$cl->{"err"}) {
   3.731 -			# Command does not contain mistakes
   3.732 -			
   3.733 -			my %commands = extract_from_cline("commands", ${$cl}->{"cline"});
   3.734 -			my %files = extract_from_cline("files", ${$cl}->{"cline"});
   3.735 -
   3.736 -			# Searching for new commands only
   3.737 -			for my $command (keys  %commands) {
   3.738 -				if (!defined $Commands_Stat{$command}) {
   3.739 -					push @{$$cl->{new_commands}}, $command;
   3.740 -				}	
   3.741 -				$Commands_Stat{$command}++;
   3.742 -			}
   3.743 -			
   3.744 -			for my $file (keys  %files) {
   3.745 -				if (!defined $Files_Stat{$file}) {
   3.746 -					push @{$$cl->{new_files}}, $file;
   3.747 -				}	
   3.748 -				$Files_Stat{$file}++;
   3.749 -			}
   3.750 -		}	
   3.751 -	}	
   3.752 -
   3.753 -}
   3.754 -
   3.755 -
   3.756 -=cut 
   3.757 -Вывести результат обработки журнала.
   3.758 -=cut
   3.759 -
   3.760 -
   3.761 -sub print_command_lines
   3.762 -{
   3.763 -	my $output_filename=$_[0];
   3.764 -	my $format = $Config{"output_format"};
   3.765 -
   3.766 -	my $course_name = $Config{"course-name"};
   3.767 -	my $course_code = $Config{"course-code"};
   3.768 -	my $course_date = $Config{"course-date"};
   3.769 -	my $course_center = $Config{"course-center"};
   3.770 -	my $course_trainer = $Config{"course-trainer"};
   3.771 -	my $course_student = $Config{"course-student"};
   3.772 -	
   3.773 -	open(OUT, ">", $output_filename)
   3.774 -		or die "Can't open $output_filename for writing\n";
   3.775 -
   3.776 -
   3.777 -
   3.778 -	if ($format eq "html") {
   3.779 -	# vvvv HTML Header 
   3.780 -		print OUT <<HEADER;
   3.781 -		<html>
   3.782 -		<head>
   3.783 -		<meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
   3.784 -		<link rel='stylesheet' href='labmaker.css' type='text/css'/>
   3.785 -		</head>
   3.786 -		<body>
   3.787 -		<script>
   3.788 -		function getElementsByClassName(Class_Name)
   3.789 -		{
   3.790 -			var Result=new Array();
   3.791 -			var All_Elements=document.all || document.getElementsByTagName('*');
   3.792 -			for (i=0; i<All_Elements.length; i++)
   3.793 -				if (All_Elements[i].className==Class_Name)
   3.794 -			Result.push(All_Elements[i]);
   3.795 -			return Result;
   3.796 -		}
   3.797 -		function ShowHide (name)
   3.798 -		{
   3.799 -			elements=getElementsByClassName(name);
   3.800 -			for(i=0; i<elements.length; i++)
   3.801 -				if (elements[i].style.display == "none")
   3.802 -					elements[i].style.display = "";
   3.803 -				else
   3.804 -					elements[i].style.display = "none";
   3.805 -				//if (elements[i].style.visibility == "hidden")
   3.806 -				//	elements[i].style.visibility = "visible";
   3.807 -				//else
   3.808 -				//	elements[i].style.visibility = "hidden";
   3.809 -		}
   3.810 -		function filter_by_output(text)
   3.811 -		{
   3.812 -			
   3.813 -			var jjj=0;
   3.814 -			
   3.815 -			elements=getElementsByClassName('command');
   3.816 -			for(i=0; i<elements.length; i++) {
   3.817 -				subelems = elements[i].getElementsByTagName('pre');
   3.818 -				for(j=0; j<subelems.length; j++) {
   3.819 -					if (subelems[j].className = 'output') {
   3.820 -						var str = new String(subelems[j].nodeValue);
   3.821 -						if (jjj != 1) { 
   3.822 -							alert(str);
   3.823 -							jjj=1;
   3.824 -						}
   3.825 -						if (str.indexOf(text) >0) 
   3.826 -							subelems[j].style.display = "none";
   3.827 -						else
   3.828 -							subelems[j].style.display = "";
   3.829 -
   3.830 -					}
   3.831 -						
   3.832 -				}
   3.833 -			}		
   3.834 -
   3.835 -		}
   3.836 -		</script>
   3.837 -		<h2>Журнал лабораторных работ</h2>
   3.838 -
   3.839 -		<p>
   3.840 -		Выполнил $course_student<br/>
   3.841 -		Проверил $course_trainer <br/>
   3.842 -		Курс $course_name ($course_code),
   3.843 -		$course_date<br/>
   3.844 -		Учебный центр $course_center <br/>
   3.845 -		</p>
   3.846 -
   3.847 -		<ul>
   3.848 -			<li><a href='#log'>Журнал</a></li>
   3.849 -			<li><a href='#stat'>Статистика</a></li>
   3.850 -			<li><a href='#help'>Справка</a></li>
   3.851 -			<li><a href='#about'>О программе</a></li>
   3.852 -		</ul>
   3.853 -
   3.854 -		<h3 id="log">Журнал</h3>
   3.855 -HEADER
   3.856 -		print OUT "<table class='visibility_form'><tr><td><form>\n";
   3.857 -		for my $element (keys %Elements_Visibility)
   3.858 -		{
   3.859 -			my @e = split /\s+/, $element;
   3.860 -			my $showhide = join "", map { "ShowHide('$_');" } @e ;
   3.861 -			print OUT "<input type='checkbox' name='$e[0]' onclick=\"$showhide\" checked>",
   3.862 -					$Elements_Visibility{$element},
   3.863 -					"</input><br>\n";
   3.864 -		}
   3.865 -		#print OUT "<input type='text' size='10' name=\"by_command\"/>".
   3.866 -		#"<input type='button' value='фильтр по командам' onclick=\"filter_by_command()\"/> <br>\n";
   3.867 -		#print OUT "<input type='text' size='10' name=\"by_output\"/>".
   3.868 -		#"<input type='button' value='фильтр по результату' ".
   3.869 -		#"onclick=\"filter_by_output(this.form.by_output.value)\"/> <br>\n";
   3.870 -
   3.871 -		print OUT "</form></td></tr></table>\n";
   3.872 -		print OUT "<table width='100%'>\n";
   3.873 -	# ^^^^ HTML Header 
   3.874 -	}
   3.875 -	else {
   3.876 -		# XML Header
   3.877 -		print OUT "<script>\n"
   3.878 -	}
   3.879 -	
   3.880 -	my $cl;
   3.881 -	my $last_tty="";
   3.882 -	my $last_day="";
   3.883 -	my $in_range=0;
   3.884 -	for my $i (@Command_Lines_Index) {
   3.885 -
   3.886 -		
   3.887 -		$cl = $Command_Lines[$i];
   3.888 -
   3.889 -		if ($Config{"from"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"from"}/) {
   3.890 -			$in_range=1;
   3.891 -			next;
   3.892 -		}
   3.893 -		if ($Config{"to"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"to"}/) {
   3.894 -			$in_range=0;
   3.895 -			next;
   3.896 -		}
   3.897 -		next if ($Config{"from"} && $Config{"to"} && !$in_range) 
   3.898 -			||
   3.899 -		    	($Config{"skip_empty"} =~ /^y/i && $cl->{"cline"} =~ /^\s*$/ )
   3.900 -			||
   3.901 -			($Config{"skip_wrong"} =~ /^y/i && $cl->{"err"} != 0)
   3.902 -			||
   3.903 -			($Config{"skip_interrupted"} =~ /^y/i && $cl->{"err"} == 130);
   3.904 -		
   3.905 -		my @new_commands=@{$cl->{"new_commands"}};
   3.906 -		my @new_files=@{$cl->{"new_files"}};
   3.907 -
   3.908 -		my $cl_class="cline";
   3.909 -		my $out_class="output";
   3.910 -		if ($cl->{"class"}) {
   3.911 -			$cl_class = $cl->{"class"}."_".$cl_class;
   3.912 -			$out_class = $cl->{"class"}."_".$out_class;
   3.913 -		}
   3.914 -
   3.915 -		my $output="";
   3.916 -		if ($Config{"head_lines"} || $Config{"tail_lines"}) {
   3.917 -			# Partialy output
   3.918 -			my @lines = split '\n', $cl->{"output"};
   3.919 -			# head
   3.920 -			my $mark=1;
   3.921 -			for (my $i=0; $i<= $#lines && $i < $Config{"head_lines"}; $i++) {
   3.922 -				$output .= $lines[$i]."\n";
   3.923 -			}
   3.924 -			# tail
   3.925 -			my $start=$#lines-$Config{"tail_lines"}+1;
   3.926 -			if ($start < 0) {
   3.927 -				$start=0;
   3.928 -				$mark=0;
   3.929 -			}	
   3.930 -			if ($start < $Config{"head_lines"}) {
   3.931 -				$start=$Config{"head_lines"};
   3.932 -				$mark=0;
   3.933 -			}	
   3.934 -			$output .= $Config{"skip_text"}."\n" if $mark;
   3.935 -			for (my $i=$start; $i<= $#lines; $i++) {
   3.936 -				$output .= $lines[$i]."\n";
   3.937 -			}
   3.938 -		} 
   3.939 -		else {
   3.940 -			# Full output
   3.941 -			$output .= $cl->{"output"};
   3.942 -		}	
   3.943 -		$output .= "^C\n" if ($cl->{"err"} eq "130");
   3.944 -
   3.945 -
   3.946 -# Printing out
   3.947 -
   3.948 -		# <command>
   3.949 -		print OUT $format eq "html" 
   3.950 -				? "<tr class='command'>\n"
   3.951 -				: "\n<action time='$cl->{hour}:$cl->{min}:$cl->{sec}' tty='$cl->{tty}'>\n";
   3.952 -						
   3.953 -		
   3.954 -		if ($format eq "html") {
   3.955 -
   3.956 -			# DAY CHANGE
   3.957 -			if ( $last_day ne $cl->{"day"}) {
   3.958 -				print OUT "<td colspan='6'><p></p><h3>День ",$cl->{"day"},"</h4></td></tr><tr>";
   3.959 -				$last_day=$cl->{"day"};
   3.960 -			}
   3.961 -
   3.962 -			# CONSOLE CHANGE
   3.963 -			if ( $last_tty ne $cl->{"tty"}) {
   3.964 -				print OUT "<td colspan='6'><table><tr><td class='ttychange' width='140' align='center'>",$cl->{"tty"},"</td><td/></tr></table></td></tr><tr>";
   3.965 -				$last_tty=$cl->{"tty"};
   3.966 -			}
   3.967 -
   3.968 -			# TIME
   3.969 -			if ($Config{"show_time"} =~ /^y/i) {
   3.970 -				print OUT "<td valign='top' class='time' width='$Config{time_width}'><pre>",
   3.971 -					$cl->{"hour"}, ":", $cl->{"min"}, ":", $cl->{"sec"},
   3.972 -					"</td>";
   3.973 -			} else {
   3.974 -				print OUT "<td width='0'/>"
   3.975 -			}
   3.976 -		}	
   3.977 -
   3.978 -		# COMMAND
   3.979 -
   3.980 -
   3.981 -		if ($format eq "html") {
   3.982 -			print OUT "<td class='script'>\n";
   3.983 -			print OUT "<pre class='$cl_class'>\n";
   3.984 -			my $cline = $cl->{"cline"};
   3.985 -			$cline =~ s/\n//;
   3.986 -			printq(\*OUT,$cl->{"prompt"},$cl->{"cline"});
   3.987 -#			printq(\*OUT,"(sudo ".$cl->{"last_command"}.")\n") if !$cl->{"euid"};
   3.988 -			print OUT "</pre>\n";
   3.989 -		} 
   3.990 -		else {
   3.991 -			print OUT "<line class='$cl_class'>\n";
   3.992 -			print OUT "<prompt>";
   3.993 -			printq(\*OUT,$cl->{"prompt"});
   3.994 -			print OUT "</prompt>";
   3.995 -			print OUT "<command>";
   3.996 -			printq(\*OUT,$cl->{"cline"});
   3.997 -			print OUT "</command>";
   3.998 -			print OUT "\n</line>\n";
   3.999 -		}
  3.1000 -
  3.1001 -		my $last_command = $cl->{"last_command"};
  3.1002 -		if (!( 
  3.1003 -		$Config{"suppress_editors"} =~ /^y/i && grep ($_ eq $last_command, @{$Config{"editors"}}) ||
  3.1004 -		$Config{"suppress_pagers"}  =~ /^y/i && grep ($_ eq $last_command, @{$Config{"pagers"}}) ||
  3.1005 -		$Config{"suppress_terminal"}=~ /^y/i && grep ($_ eq $last_command, @{$Config{"terminal"}})
  3.1006 -			)) {
  3.1007 -
  3.1008 -			if ($format eq "html") {
  3.1009 -				print OUT "<pre class='$out_class'>";
  3.1010 -				printq(\*OUT,$output);
  3.1011 -				print OUT "</pre>\n";
  3.1012 -			} 
  3.1013 -			else {
  3.1014 -				print OUT "<output class='$out_class'>\n";
  3.1015 -				printq(\*OUT,$output);
  3.1016 -				print OUT "</output>\n";
  3.1017 -			}
  3.1018 -		}	
  3.1019 -
  3.1020 -		# DIFF
  3.1021 -		if ( $Config{"show_diffs"} =~ /^y/i && $cl->{"diff"}) {
  3.1022 -			if ($format eq "html") {
  3.1023 -				#print Dumper(%{$cl->{"diff"}});
  3.1024 -				print OUT "<table><tr><td width='5'/><td class='diff'><pre>";
  3.1025 -				printq(\*OUT,${$Diffs[$cl->{"diff"}]}{"text"});
  3.1026 -				print OUT "</pre></td></tr></table>";
  3.1027 -			}
  3.1028 -			else {
  3.1029 -				print OUT "<diff>\n";
  3.1030 -				printq(\*OUT,${$Diffs[$cl->{"diff"}]}{"text"});
  3.1031 -				print OUT "</diff>\n";
  3.1032 -			}
  3.1033 -		}
  3.1034 -
  3.1035 -		# COMMENT
  3.1036 -		if ( $Config{"show_comments"} =~ /^y/i) {
  3.1037 -			my $comment = make_comment(join(" ",@new_commands), join (" ",@new_files));
  3.1038 -			if ($comment) {
  3.1039 -				if ($format eq "html") {
  3.1040 -					print OUT "<table width='$Config{comment_width}'>".
  3.1041 -							"<tr><td width='5'/><td>";
  3.1042 -					print OUT "<table class='note' width='100%'>";
  3.1043 -					print OUT $comment;
  3.1044 -					print OUT "</table>\n";
  3.1045 -					print OUT "</td></tr></table>";
  3.1046 -				}
  3.1047 -			#	else {
  3.1048 -			#		print OUT "<comment>";
  3.1049 -			#		printq(\*OUT,$comment);
  3.1050 -			#		print OUT "</comment>";
  3.1051 -			#	}
  3.1052 -			}
  3.1053 -		}
  3.1054 -
  3.1055 -		if ($format eq "html") {
  3.1056 -			print OUT "</td>\n";
  3.1057 -			print OUT "</tr>\n";
  3.1058 -		}
  3.1059 -		else {
  3.1060 -			print OUT "</action>\n";
  3.1061 -		}
  3.1062 -		
  3.1063 -	}
  3.1064 -	if ($format eq "html") {
  3.1065 -		print OUT "</table>\n";
  3.1066 -
  3.1067 -		print OUT "<hr/>";
  3.1068 -		print OUT "<h3 id='stat'>Статистика</h4>";
  3.1069 -		print OUT "Статистическая информация о журнале<br/>";
  3.1070 -		print OUT "<hr/>";
  3.1071 -		print OUT "<h3 id='help'>Справка</h4>";
  3.1072 -		print OUT "$Html_Help<br/>";
  3.1073 -		print OUT "<hr/>";
  3.1074 -		print OUT "<h3 a='about'>О программе</h4>";
  3.1075 -		print OUT "$Html_About";
  3.1076 -		print OUT "</body>\n";
  3.1077 -		print OUT "</html>\n";
  3.1078 -	} 
  3.1079 -	else {
  3.1080 -		print OUT "</script>\n";
  3.1081 -	}
  3.1082 -	close(OUT);
  3.1083 -}
  3.1084 -
  3.1085 -sub read_config_file
  3.1086 -{
  3.1087 -	my $config = $_[0];
  3.1088 -	my $filename = $_[1];
  3.1089 -	open(CONFIG, "$filename")
  3.1090 -		or return;
  3.1091 -	while (<CONFIG>) {
  3.1092 -		s/#.*//;
  3.1093 -		next if /^\s*$/;
  3.1094 -		my ($var, $val) =  split /\s*=\s*/, $_, 2;
  3.1095 -		$var =~ s/\s*//;
  3.1096 -		$config->{$var} = $val;
  3.1097 -	}
  3.1098 -	close(CONFIG);
  3.1099 -}
  3.1100 -
  3.1101 -
  3.1102 -sub print_command_lines2
  3.1103 -{
  3.1104 -	my $output_filename=$_[0];
  3.1105 -	open(OUT, ">", $output_filename)
  3.1106 -		or die "Can't open $output_filename for writing\n";
  3.1107 -
  3.1108 -
  3.1109 -	print OUT <<OUT;
  3.1110 -<log>
  3.1111 -OUT
  3.1112 -
  3.1113 -	my $cl;
  3.1114 -	for my $i (@Command_Lines_Index) {
  3.1115 -
  3.1116 -		
  3.1117 -		$cl = $Command_Lines[$i];
  3.1118 -
  3.1119 -
  3.1120 -# Printing out
  3.1121 -		print OUT <<OUT;
  3.1122 -	<command>
  3.1123 -		<day>$cl->{day}</day>
  3.1124 -		<hour>$cl->{hour}</hour>
  3.1125 -		<min>$cl->{min}</min>
  3.1126 -		<sec>$cl->{sec}</sec>
  3.1127 -		<tty>$cl->{tty}</tty>
  3.1128 -		<uid>$cl->{uid}</uid>
  3.1129 -		<euid>$cl->{euid}</euid>
  3.1130 -		<prompt>$cl->{prompt}</prompt>
  3.1131 -		<cline>$cl->{cline}</cline>
  3.1132 -		<status>$cl->{err}</cline>
  3.1133 -		<output>
  3.1134 -$cl->{output}</output>
  3.1135 -	</command>
  3.1136 -OUT
  3.1137 -	}
  3.1138 -
  3.1139 -	for my $diff (@Diffs) {
  3.1140 -
  3.1141 -		print OUT <<OUT;
  3.1142 -	<diff>
  3.1143 -		<path>$diff->{path}</path>
  3.1144 -		<uid>$diff->{uid}</uid>
  3.1145 -		<day>$diff->{day}</day>
  3.1146 -		<hour>$diff->{hour}</hour>
  3.1147 -		<min>$diff->{min}</min>
  3.1148 -		<sec>$diff->{sec}</sec>
  3.1149 -		<text>
  3.1150 -$diff->{text}</text>
  3.1151 -	</diff>
  3.1152 -OUT
  3.1153 -	}
  3.1154 -
  3.1155 -	print OUT <<OUT;
  3.1156 -</log>
  3.1157 -OUT
  3.1158 -}
  3.1159 -
  3.1160 -
  3.1161 -$| = 1;
  3.1162 -
  3.1163 -my %file_config;
  3.1164 -my %argv_config;
  3.1165 -init_variables;
  3.1166 -read_config_file(\%file_config, $Config_File);
  3.1167 -GetOptions(\%argv_config, map "$_=s", keys %Config);
  3.1168 -%Config = (%Config, %file_config, %argv_config);
  3.1169 -
  3.1170 -my $i=0;
  3.1171 -
  3.1172 -for my $lab_log (split (/\s+/, $Config{"diffs"} || $Config{"input"})) 
  3.1173 -{
  3.1174 -	load_diff_files($lab_log);
  3.1175 -}
  3.1176 -
  3.1177 -for my $lab_log (split /\s+/, $Config{"input"}) 
  3.1178 -{
  3.1179 -	my $tofile=$Config{"output"};
  3.1180 -	$tofile =~ s/$Config{"output_mask"}/$i/;
  3.1181 -	#load_diff_files($lab_log);
  3.1182 -	load_command_lines($lab_log, $Config{"input_mask"});
  3.1183 -	sort_command_lines;
  3.1184 - 	process_command_lines($lab_log);
  3.1185 -	print_command_lines($tofile);
  3.1186 -	$i++;
  3.1187 -}
  3.1188 -
  3.1189 -
     4.1 --- a/lm-ssh	Mon Jul 21 11:24:53 2008 +0300
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,31 +0,0 @@
     4.4 -#!/bin/sh
     4.5 -#\
     4.6 -exec expect -- "$0" ${1+"$@"}
     4.7 -eval spawn ssh $argv
     4.8 -set timeout 1
     4.9 -expect {
    4.10 -	eof { 
    4.11 -	}
    4.12 -	"(yes/no)? " {
    4.13 -		send "yes\n"
    4.14 -		exp_continue 
    4.15 -	}
    4.16 -	assword: {
    4.17 -		send "rootpass\n"
    4.18 -	}
    4.19 -	timeout {
    4.20 -		interact -nobuffer
    4.21 -	}
    4.22 -}
    4.23 -expect {	
    4.24 -	eof { 
    4.25 -	}
    4.26 -	assword: {
    4.27 -		send "rootpass\n"
    4.28 -	}
    4.29 -
    4.30 -	timeout {
    4.31 -		interact -nobuffer
    4.32 -	}
    4.33 -}	
    4.34 -
     5.1 --- a/taillast.pl	Mon Jul 21 11:24:53 2008 +0300
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,8 +0,0 @@
     5.4 -#!/usr/bin/perl
     5.5 -
     5.6 -for $d (@ARGV) {
     5.7 -	push @d, glob("$d/*");
     5.8 -}
     5.9 -@{f} =  sort { (stat(${a}))[9] <=> (stat(${b}))[9] } (@d); 
    5.10 -print "tail -f ${f[$#f]}\n";
    5.11 -__END__