# HG changeset patch # User igor@chub.in # Date 1216632493 -10800 # Node ID f9d0d35618f837078c8e73949a30ae8c8b4914d0 # Parent 93e08c4b54edd762e2e5c2139e7f37db6e957ef6 Удалены файлы из labmaker Удалены файлы, которые переползли в репозиторий из проекта labmaker Если кому-то нужны эти файлы, они есть в старом CVS-репозитории lilalo. Удаление лишних файлов ещё полностью не завершено. Ещё будем удалять diff -r 93e08c4b54ed -r f9d0d35618f8 lm --- a/lm Mon Jul 21 11:24:53 2008 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,555 +0,0 @@ -#!/usr/bin/perl - - -use strict; -use Data::Dumper; -use Switch; -use XML::Simple; -use Getopt::Long; -use utf8; - -use lib "/usr/local/bin"; -use l3config; - -our $XMLClass; -our $XMLCourse; -our @Labs; - -our %Machines; # Machines list from class.xml -our @SelectedMachines; # Machines list given as the command line argument - -our $Config_File = "labmaker.conf"; -our %Config_ = ( - "show_host" => "no", - - # Вспомогательные программы - #"l3-report" => "./lm-report", - "l3-report" => "./l3-report", - - # Каталоги - "path_lilalo" => "/var/lilalo/", - "path_classes" => "/var/lilalo/classes/", - "path_lablogs" => "/var/lilalo/lablogs/", - "courses_path" => "/var/lilalo/courses/", - "outpath" => "/var/lilalo/out/", - "path_web" => "/var/www/l3", # Путь к web-отчётам - "path_share" => "./share/", # Путь к web-отчётам - - # Файлы - "runfile" => "lm.run", - "logfile" => "lm.log", - - "class" => "class", # Имя файла класса - "class_suffix" => ".xml", # Cуффикс файла класса - "classfile" => "", - - "sshkey" => "$ENV{HOME}/.ssh/id_dsa.pub", - "lmssh" => "./lm-ssh", - "lminstall" => "./lm-install", - "ssh_user" => "root", -); - -our %Run = ( - "lab" => "" -); - -our %Scripts; - -sub load_class; -sub load_config; -sub load_course; -sub load_scripts; - -sub lm_get; -sub lm_next; -sub lm_prev; -sub lm_start; -sub lm_stop; -sub lm_set; -sub lm_do; -sub lm_report; -sub lm_show_hosts; -sub lm_show_email; -sub lm_show_labs; - -sub load_run; -sub save_run; -sub print_log; -sub print_usage_info; -sub main(); - -main(); - -sub main() -{ - binmode STDOUT, ":utf8"; - - if (! @ARGV) { - print_usage_info(); - exit(0); - } - - if ($ARGV[0] eq "get") { - lm_get; - exit(0); - } - - init_config(); - #load_config; - load_run; - load_scripts; - load_class; - load_course; - - my $arg = join " ", @ARGV; - - # Getting @SelectedMachines if any - if ($arg =~ s/@(.*?)\s//) { - my $machines = $1; - my @list = split /,/, $machines; - for my $interval (@list) { - my ($first, $last) = split /-/, $interval; - - push @SelectedMachines, $first; - while ($first < $last) { - push @SelectedMachines, ++$first; - } - } - } - - # Choose command to do - switch ($arg) { - case "next" { lm_next } - case "prev" { lm_prev } - case /set / { $arg =~ /set (.*)/; lm_set $1 } - case "report" { lm_report } - case "start" { lm_start } - case "stop" { lm_stop } - case "show hosts" { lm_show_hosts } - case "show email" { lm_show_email } - case "show labs" { lm_show_labs } - case /do / { $arg =~ /do (.*)/; lm_do "$1" } - else { print_usage_info() } - } - save_run; - exit(0); -} - -sub load_scripts -{ - open (SCRIPTS, "$Config{l3scripts}") - or die "Cant open l3scripts file: ".$Config{l3scripts}.": $!\n"; - binmode SCRIPTS, ":utf8"; - local $/; - $_=; - close(SCRIPTS); - - %Scripts = ("empty-element", split (/###(.*)\n/)); - delete($Scripts{"empty-element"}); - -} - -sub load_config -{ - my %file_config; - my %argv_config; - #read_config_file(\%file_config, $Config_File); - GetOptions(\%argv_config, map "$_=s", keys %Config); - %Config = (%Config, %file_config, %argv_config); -} - -sub load_course -{ - $XMLCourse = XMLin($Config{"courses_path"}.$XMLClass->{"course"}.".xml", ForceArray => 1 ) - or die "Can't open file of the course ",$XMLClass->{"course"}," [with .xml extension]\n"; -# print Dumper($XMLCourse); - for my $lab (@{$XMLCourse->{"module"}}) { - push @Labs, $lab->{"code"}; - } -} - -sub load_class -{ - my $classfile = - $Config{"classfile"} || - $Config{"path_classes"}."/".$Config{"class"}.$Config{"class_suffix"}; - $XMLClass = XMLin($classfile , ForceArray => [ 'student' ] ) - or die "Can't open file of the class ",$classfile,"\n"; - - for my $student (@{$XMLClass->{"student"}}) { - $Machines{$student->{"host"}} = { - "name" => "$student->{firstname} $student->{surname}", - "firstname" => "$student->{firstname}", - "user" => "$student->{user}", - "email" => "$student->{email}", - "student" => $student, - } - } -# print Dumper($XMLClass); -# print Dumper(\%Machines); -} - -sub lm_get -{ - print "Getting class description file..."; - if (system("cd $Config{path_classes}; rm -f class.xml ; wget xgu.ru/l3/classes/class.xml") ==0 ) - { - print "Ok\n"; - } - else { - die "Can't load class file\n" - } -} - - -sub lm_next -{ - for(my $i=0; $i<=$#Labs; $i++){ - if ( $Labs[$i] eq $Run{"lab"} ) { - if ($i < $#Labs) { - lm_set($Labs[$i+1]); - return ; - } else { - die "Lab ", $Run{"lab"}, " is the last. Switch to next lab is impossible" - } - } - - } - die "Lab ", $Run{"lab"}, " not found. Don't know which is next" -} - -sub lm_prev -# Switch to previous lab -{ - for(my $i=0; $i<=$#Labs; $i++){ - if ( $Labs[$i] eq $Run{"lab"} ) { - if ($i > 0) { - lm_set($Labs[$i-1]); - return ; - } else { - die "Lab ", $Run{"lab"}, " is the first. Switch to previous lab is impossible" - } - } - - } - die "Lab ", $Run{"lab"}, " not found. Don't know which is previous" -} - -sub lm_set -# Switch to $_[0] lab -# FIXME -{ - my $lab = shift; - print "Current lab is $lab\n"; - $Run{"lab"} = "$lab"; - lm_do "setlab", $lab; -} - - -sub lm_start -# Start new training day -{ - print_log(`date`." STARTED\n"); - if ($Run{"lab"}) { - lm_next; - } - else - { - # First lab in the course - lm_set($Labs[0]); - } -} - -sub lm_stop -# Stop this training day -{ - print_log(`date`." STOPPED\n"); -} - - -sub lm_show_hosts -# Show hosts used to run a commands -{ - my $i=1; - for my $m (sort keys %Machines) { - if (!@SelectedMachines || grep /^$i$/, @SelectedMachines) { - print "($i)","\t",$m,"\t",$Machines{$m}->{"name"},"\n"; - } - $i++; - } -} - -sub lm_show_email -# Show hosts used to run a commands -{ - my $i=1; - for my $m (sort keys %Machines) { - if (!@SelectedMachines || grep /^$i$/, @SelectedMachines) { - print $Machines{$m}->{"email"},"\t",$Machines{$m}->{"name"},"\n"; - } - $i++; - } -} - -sub lm_show_labs -# Show hosts used to run a commands -{ - my $i=1; - for my $lab (@Labs) { - print $lab; - print "*" if $lab eq $Run{"lab"}; - print "\n"; - } -} - -sub lm_do -# Do the $_[0] command on all of the hosts -{ - my $command = shift; - my $arg = join " ", @_; - my $i=1; - - my %myenv = ( %Config, - lab => $arg, - center => $XMLClass->{"center"}, - course => $XMLClass->{"course"}, - date => $XMLClass->{"date"}, - stopdate => $XMLClass->{"stop-date"}, - instructor => $XMLClass->{"instructor"}->{"firstname"}." ".$XMLClass->{"instructor"}->{"surname"}, - manager => $XMLClass->{"manager"}->{"firstname"}." ".$XMLClass->{"manager"}->{"surname"}, - coursepath => $XMLCourse->{"path"}, - ); - - if (grep { $_ eq "PRE-$command"} keys %Scripts) { - $_=$Scripts{"PRE-$command"}; - s/\$(\w+)/$myenv{$1}/ge; - open(SHELL, "|/bin/sh -s"); - binmode SHELL, ":utf8"; - print SHELL $_; - close (SHELL); - } - - - for my $m (sort keys %Machines) { - if (!@SelectedMachines || grep $_ eq $i, @SelectedMachines) { - print "$m:\n" if $Config{"show_host"} =~ /y/i; - - %myenv = ( %myenv, - host => $m, - ipaddress => $Machines{$m}->{"ipaddress"}, - dirs => "/root /home/".$Machines{$m}->{"user"}, - lablogs => $Config{"path_lablogs"}."/". - $XMLClass->{"course"}."/". - $XMLClass->{"date"}."/". - "$m", - email => $Machines{$m}->{"student"}->{"email"}, - company => $Machines{$m}->{"student"}->{"company"}, - name => $Machines{$m}->{"name"}, - firstname => $Machines{$m}->{"firstname"}, - ); - if (grep { $_ eq $command} keys %Scripts) { - $_=$Scripts{"$command"}; - s/\$(\w+)/$myenv{$1}/ge; - open(SHELL, "|/bin/sh -s"); - binmode SHELL, ":utf8"; - print SHELL $_; - close (SHELL); - } - else { - my $res = `ssh $Config{"ssh_user"}\@$m $command`; - if ($res) { - my $count = ($res =~ s/(^)/$m: /mg); - print $res; - print "\n" if ($count > 1); - } - } - } - $i++; - } - - if (grep { $_ eq "POST-$command"} keys %Scripts) { - $_=$Scripts{"POST-$command"}; - s/\$(\w+)/$myenv{$1}/ge; - open(SHELL, "|/bin/sh -s"); - binmode SHELL, ":utf8"; - print SHELL $_; - close (SHELL); - } -} - - - -=cut comment - -lm report - -Построить html представление для журналов текущего класса. -Для построения используется скрипт l3-report. - -=cut - -sub lm_report -{ - - my $webdir = $Config{"path_web"}; - my $course=$XMLClass->{"course"}; - my $date=$XMLClass->{"date"}; - my $encoding=$XMLClass->{"charset"}; - - my $center = $XMLClass->{"center"}; - my $instructor = $XMLClass->{"instructor"}->{"firstname"}." ".$XMLClass->{"instructor"}->{"surname"}; - my $course_name = $XMLCourse->{"fullname"}[0]; - - - # Собственно журналы - - for my $student (@{$XMLClass->{"student"}}) { - my $user = $student->{"user"}; - my $hostname = $student->{"host"}; - my $encoding = $student->{"charset"}; - my $student_name = $student->{"firstname"}." ".$student->{"surname"}; - - system("mkdir -p $webdir/$date/$hostname"); - system("cp ".$Config{"path_share"}."/*.{ico,css} $webdir/$date/$hostname"); - system($Config{"l3-report"}. - " --input ".$Config{"path_lablogs"}."/$course/$date/$hostname/$user". - " --diffs ".$Config{"path_lablogs"}."/$course/$date/$hostname/$user ". - $Config{"path_lablogs"}."/$course/$date/$hostname/root". - " --output $webdir/$date/$hostname/$user.html". - " --course-name '$course_name'". - " --course-code '$course'". - " --course-date '$date'". - " --course-center '$center'". - " --course-student '$student_name'". - " --course-trainer '$instructor'". - " --encoding $encoding" - ); - system($Config{"l3-report"}. - " --input ".$Config{"path_lablogs"}."/$course/$date/$hostname/root". - " --diffs ".$Config{"path_lablogs"}."/$course/$date/$hostname/root ". - " --output $webdir/$date/$hostname/root.html". - " --course-name '$course_name'". - " --course-code '$course'". - " --course-date '$date'". - " --course-center '$center'". - " --course-student '$student_name'". - " --course-trainer '$instructor'". - " --encoding $encoding" - ); - } - - # Индекс для данного класса - - my $head; - - $head="Журналы лабораторных работ"; - open(HTML, ">$webdir/$date/index.html") - or die "Can't open $webdir/$date/index.html for writing"; - binmode HTML, ":utf8"; - print HTML < - - - $head - - -

$head

-

- Курс: $course_name ($course)
- Начало: $date
- Учебный центр: $center
- Инструктор: $instructor
-

- -HEAD - for my $student (@{$XMLClass->{"student"}}) { - my $user = $student->{"user"}; - my $hostname = $student->{"host"}; - print HTML "\n"; - print HTML "\n"; - print HTML "\n"; - print HTML "\n"; - print HTML "\n"; - print HTML "\n"; - } - print HTML < - -TAIL - close (HTML); - - - -} - -sub load_run -{ - my $runfile = $Config{"path_labmaker"}."/".$Config{"path_runfile"}; - open (RUN, $runfile) - or return; - while () { - chomp; - my ($var, $val) = split /\s+/,$_,2; - $Run{$var}=$val; - } - close (RUN); -} - -sub save_run -{ - my $runfile = $Config{"path_labmaker"}."/".$Config{"path_runfile"}; - open (RN, "$runfile") - or die "Can't save running state to $runfile"; - for my $var (keys %Run) { - print RN $var,"\t",$Run{$var},"\n"; - } - close (RN); -} - -sub print_log -{ - my $logfile = $Config{"path_labmaker"}."/".$Config{"path_logfile"}; - open (LOG, ">>$logfile") - or die "Can't open logfile $logfile for writing"; - print LOG @_; - close (LOG); -} - - -sub print_usage_info -{ - print "Usage:\n\n\t$0 [host-list] command\n"; - print <<'USAGE'; - -Commands: - - next -- next lab - prev -- prev lab - set LAB -- set current lab to LAB - start -- start this day training - stop -- stop this day training - show hosts -- show available hosts in the class - show labs -- show available labs in the course - do COMMAND -- do specified command on the hosts of hostlist - report -- generate XML/HTML reports - - -do commands: - - install [PROFILE] -- install profile - -Host list: - - @N -- machine N - @N1-N2 -- all of the machines from N1 to N2 - @N1,N2,N3 -- machine N1, N2 and N3 - - N* is numbers or domain names of the machines. - - If host list is not specified, - command is executed on all of the machines - -USAGE -} - - diff -r 93e08c4b54ed -r f9d0d35618f8 lm-install --- a/lm-install Mon Jul 21 11:24:53 2008 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +0,0 @@ -#!/bin/sh - -# Use -d to deinstall labmaker -# You can specify directory list to install LabMaker as command line parameters -# or set it in $users_to_install variable - -# CONFIGURABLE SECTION start -#users_to_install="/home/your-user-here /root" -# CONFIGURABLE SECTION stop - -first_lab=T1 -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' -temp_file=/tmp/lm-install-$$ -arg=$@ - -show_usage() -{ - cat << USAGE - -$0 [-d] path... - - * Use -d to deinstall labmaker - * You can specify directory list to install LabMaker as command line parameters - or set it in \$users_to_install variable in the script - -Example: - - Command - # $0 /root /home/user - installs labmaker to /root and /home/user directories - -USAGE -} - -install_to_profile() -{ - profile=$1 - cat <<'LM_bash_profile' > $temp_file -# LabMaker:START -/usr/local/bin/l3-agent -# LabMaker:END -LM_bash_profile - cat $profile \ - | sed '/LabMaker:START/,/LabMaker:END/ d' \ - >> $temp_file - cat $temp_file > $profile - rm $temp_file -} - -uninstall_from_profile() -{ - profile=$1 - cat $profile \ - | sed '/LabMaker:START/,/LabMaker:END/ d' \ - > $temp_file - cat $temp_file > $profile - rm $temp_file -} - -install_to_bashrc() -{ - profile=$1 - cat $profile \ - | sed '/LabMaker:START/,/LabMaker:END/ d' \ - > $temp_file - cat <<'LM_bash_profile' >> $temp_file -# LabMaker:START -LMHOME=~/.lilalo -mkdir -p ${LMHOME} - -uname -a | grep -qi bsd && bsd=yes -flush="-f" #linux -[ -n "$bsd" ] && flush="-t 0" #freebsd - -tty=`tty` -this_term=`w | grep "${tty##/dev/}" | awk '{print $8;}'` -# freeBSD: -[ -n "$bsd" ] && this_term=`w | grep "${tty##/dev/tty}" | awk '{print $6;}'` - - -export PS1='\[` - a="$?"; - HIDDEN=$([ "$a" = 0 ] || echo -n ^"$a")$(echo -n _${UID}_)$(echo -n _$$_)$(date\ - +"%j$(cat ${LMHOME}/lab 2>/dev/null) %H:%M:%S"); - echo $HIDDEN`\033[50D\033[K\][\u@\h:\W]\$ ' - -if [ -n "$this_term" ] && echo $this_term | grep -qv script -then - session_id=${tty##*/}-$$ - parent=`cat /proc/$PPID/cmdline 2> /dev/null` - system=`uname -rs` - login_from=`who | grep "${tty##/dev/}" | awk '{print $6;}' | tr -d '()'` - #[ -n "$bsd" ] && login_from="" #FIXME! - start_time=`date +%s` - hostname=`hostname -f 2> /dev/null` - [ -n "$bsd" ] && hostname=`hostname` - - cat < $LMHOME/${session_id}.info - -$session_id -$hostname -$USER -$UID -$login_from -$tty -$system -$parent -$PPID -$$ -$start_time - -INFO - - exec script $flush -q $LMHOME/${session_id}.script -fi -# LabMaker:END -LM_bash_profile - cat $temp_file > $profile - rm $temp_file -} - -uninstall_from_bashrc() -{ - profile=$1 - cat $profile \ - | sed '/LabMaker:START/,/LabMaker:END/ d' \ - > $temp_file - cat $temp_file > $profile - rm $temp_file -} - -install_editor() -{ -editor=$1 -[ -e $editor.orig ] && cp $editor.orig $editor -cp $editor $editor.orig -cat <<'editor_wrapper' | sed "s@EDITOR@$editor@" > $editor -#!/bin/sh - -LMHOME=~/.lilalo -if [ "${1#-}" = "$1" -a -d "$LMHOME" ] -then - LAB=`cat $LMHOME/lab` - TIME="`date +%j${LAB}_%H:%M:%S`" - DIR="" - [ "${1#/}" = "$1" ] && DIR=$PWD/ - DIFFNAME=$PPID_${TIME}_`echo $DIR$1| sed s@_@__@ | sed 's@/@_@g'`.diff - tmp="/tmp/lm-saved-$$" - touch $1 - cp -- "$1" $tmp 2> /dev/null - EDITOR.orig "$@" || ERR=1 - diff $tmp $1 > $LMHOME/$DIFFNAME 2> /dev/null - rm $tmp 2> /dev/null - if [ "$ERR" = 1 ] - then - false - else - true - fi -else - exec EDITOR.orig "$@" -fi -editor_wrapper - -} - - -uninstall_editor() -{ - editor=$1 - [ -e $editor.orig ] && mv $editor.orig $editor -} - -if [ "$1" != "-d" ] -then - # INSTALLING LM - if [ $# -gt 0 ] - then - users_to_install="$*" - fi - - if [ -z "$users_to_install" ] - then - show_usage - exit - fi - - for home in $users_to_install - do - # fix this! - user=${home%/} - user=${user##*/} - mkdir -p $home/.lilalo - echo $first_lab > $home/.lilalo/lab - chown -R $user $home/.lilalo - - #if [ ! -e $home/.bash_profile ] - #then - # echo '. ~/.bashrc' >> ~/.bash_profile - #fi - #[ -e $home/.bash_profile ] \ - # && install_to_profile $home/.bash_profile \ - # && echo LabMaker is installed to $home/.bash_profile - - echo Don\'t forget to check .bash_profile for .bashrc call - - [ -e $home/.bash_profile ] && install_to_profile $home/.bash_profile \ - && install_to_profile $home/.bash_profile \ - && echo LabMaker is installed to $home/.bash_profile - - touch $home/.bashrc - [ -e $home/.bashrc ] && install_to_bashrc $home/.bashrc \ - && install_to_bashrc $home/.bashrc \ - && echo LabMaker is installed to $home/.bashrc - done - - for editor in $editors_to_install - do - [ -e $editor ] \ - && install_editor $editor \ - && echo LabMaker is installed to $editor - done -else -# UNINSTALLING LM - shift - users_to_install="$*" - for user in $users_to_install - do - home=$user - mkdir -p $home/.lilalo - echo $first_lab > $home/.lilalo/lab - chown -R ${user##*/} $home/.lilalo - - #if [ ! -e $home/.bash_profile ] - #then - # echo '. ~/.bashrc' >> ~/.bash_profile - #fi - #[ -e $home/.bash_profile ] \ - # && uninstall_from_profile $home/.bash_profile \ - # && echo LabMaker is uninstalled from $home/.bash_profile - - [ -e $home/.profile ] && uninstall_from_profile $home/.profile \ - && uninstall_from_profile $home/.profile \ - && echo LabMaker is uninstalled from $home/.profile - - touch $home/.bashrc - [ -e $home/.bashrc ] && uninstall_from_bashrc $home/.bashrc \ - && uninstall_from_bashrc $home/.bashrc \ - && echo LabMaker is uninstalled from $home/.bashrc - done - - for editor in $editors_to_install - do - [ -e $editor ] \ - && uninstall_editor $editor \ - && echo LabMaker is uninstalled from $editor - done -fi diff -r 93e08c4b54ed -r f9d0d35618f8 lm-report --- a/lm-report Mon Jul 21 11:24:53 2008 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1186 +0,0 @@ -#!/usr/bin/perl -w - -# -# (c) Igor Chubin, imchubin@mail.ru, 2004-2005 -# - -use strict; -use Getopt::Long; -use Term::VT102; -use Text::Iconv; -use Data::Dumper; - -our $Config_File = "labmaker.conf"; -our %Config = ( - "skip_empty" => "yes", - "skip_interrupted" => "no", - "skip_wrong" => "no", - "editors" => ["vi", "pico", "ee", "vim"], - "pagers" => ["more", "less", "zmore", "zless", "info", - "man", "mc", "trafshow", "screen", "cfdisk", - "trafshow-bsd", "yes", "lynx", "links", "centericq" - ], - "terminal" => ["mc"], - "suppress_editors" => "yes", - "suppress_pagers" => "yes", - "suppress_terminal" => "yes", - - "terminal_width" => 100, - "terminal_height" => 100, - "verbose" => "yes", - - "head_lines" => 5, - "tail_lines" => 5, - "skip_text" => "...", - "show_time" => "yes", - "show_diffs" => "yes", - "show_comments" => "yes", - - "input" => "/root/.labmaker", - "diffs" => "", - "input_mask" => "*.script", - "encoding" => "utf-8", - - "output" => "/var/www/lm/reportINDEX.html", - #"output" => "report.xml", - "output_mask" => "INDEX", - "output_format" => "html", - - "signature" => "#lm:", - "from" => "", - "to" => "", - "lab" => "", - "keywords" => "linux command", - "files_keywords" => "linux file", - - comment_width => "300", - time_width => "60", - - "course-name" => "", - "course-code" => "", - "course-date" => "", - "course-center" => "", - "course-trainer" => "", - "course-student" => "", - - ); - -our @Command_Lines; -our @Command_Lines_Index; -our @Diffs; - -our %Commands_Stat; # Statistics about commands usage -our %Files_Stat; # Statistics about commands usage - -our %Search_Machines = ( - "google" => { "query" => "http://www.google.com/search?q=" , - "icon" => "google.ico" }, - "freebsd" => { "query" => "http://www.freebsd.org/cgi/man.cgi?query=", - "icon" => "freebsd.ico" }, - "linux" => { "query" => "http://man.he.net/?topic=", - "icon" => "linux.ico"}, - "opennet" => { "query" => "http://www.opennet.ru/search.shtml?words=", - "icon" => "opennet.ico"}, - "local" => { "query" => "http://www.freebsd.org/cgi/man.cgi?query=", - "icon" => "freebsd.ico" }, - - ); - -our %Elements_Visibility = ( - "note" => "замечания", - "diff" => "редактор", - "time" => "время", - "ttychange" => "терминал", - "wrong_output wrong_cline wrong_root_output wrong_root_cline" - => "команды с ошибками", - "interrupted_output interrupted_cline interrupted_root_output interrupted_root_cline" - => "прерванные команды", - "tab_completion_output tab_completion_cline" - => "продолжение с помощью tab" -); - -sub init_variables; -our $Html_Help; -our $Html_About; - - -sub load_diff_files -{ - my @pathes = @_; - - for my $path (@pathes) { - my $template = "*.diff"; - my @files = <$path/$template>; - my $i=0; - for my $file (@files) { - my %diff; - - $diff{"path"}=$path; - $diff{"uid"}="SET THIS"; - -# Сейчас UID определяется из названия каталога -# откуда берутся diff-файлы -# Это неправильно -# -# ВАРИАНТ: -# К файлам жураналам должны прилагаться ситемны файлы, -# мз которых и будет определяться соответствие -# имён пользователей их uid'ам -# - $diff{"uid"} = 0 if $path =~ m@/root/@; - - $diff{"bind_to"}=""; - $diff{"time_range"}=-1; - - next if not $file=~m@/(D?[0-9][0-9]?[0-9]?)[^/]*?([0-9]*):([0-9]*):?([0-9]*)@; - $diff{"day"}=$1 || ""; - $diff{"hour"}=$2; - $diff{"min"}=$3; - $diff{"sec"}=$4 || 0; - - $diff{"index"}=$i; - - print "diff loaded: $diff{day} $diff{hour}:$diff{min}:$diff{sec}\n"; - - local $/; - open (F, "$file") - or return "Can't open file $file ($_[0]) for reading"; - my $text = ; - if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i) { - my $converter = Text::Iconv->new($Config{"encoding"}, "utf-8"); - $text = $converter->convert($text); - } - close(F); - $diff{"text"}=$text; - #print "$file loaded ($diff{day})\n"; - - push @Diffs, \%diff; - $i++; - } - } -} - - -sub bind_diff -{ -# my $path = shift; -# my $pid = shift; -# my $day = shift; -# my $lab = shift; - - print "Trying to bind diff...\n"; - - my $cl = shift; - my $hour = $cl->{"hour"}; - my $min = $cl->{"min"}; - my $sec = $cl->{"sec"}; - - my $min_dt = 10000; - - for my $diff (@Diffs) { - # Check here date, time and user - next if ($diff->{"day"} && $cl->{"day"} && ($cl->{"day"} ne $diff->{"day"})); - #next if (!$diff->{"uid"} && $cl->{"euid"} != $diff->{"uid"}); - - my $dt=($diff->{"hour"}-$hour)*3600 +($diff->{"min"}-$min)*60 + ($diff->{"sec"}-$sec); - if ($dt >0 && $dt < $min_dt && ($diff->{"time_range"} <0 || $dt < $diff->{"time_range"})) { - print "Approppriate diff found: dt=$dt\n"; - if ($diff->{"bind_to"}) { - undef $diff->{"bind_to"}->{"diff"}; - }; - $diff->{"time_range"}=$dt; - $diff->{"bind_to"}=$cl; - - $cl->{"diff"} = $diff->{"index"}; - $min_dt = $dt; - } - - } -} - - -sub extract_from_cline -# Разобрать командную строку $_[1] и возвратить хэш, содержащий -# номер первого появление команды в строке: -# команда => первая позиция -{ - my $what = $_[0]; - my $cline = $_[1]; - my @lists = split /\;/, $cline; - - - my @commands = (); - for my $list (@lists) { - push @commands, split /\|/, $list; - } - - my %commands; - my %files; - my $i=0; - for my $command (@commands) { - $command =~ /\s*(\S+)\s*(.*)/; - if ($1 && $1 eq "sudo" ) { - $commands{"$1"}=$i++; - $command =~ s/\s*sudo\s+//; - } - $command =~ /\s*(\S+)\s*(.*)/; - if ($1 && !defined $commands{"$1"}) { - $commands{"$1"}=$i++; - }; - if ($2) { - my $args = $2; - my @args = split (/\s+/, $args); - for my $a (@args) { - $files{"$a"}=$i++ - if !defined $files{"$a"}; - }; - - - } - } - - if ($what eq "commands") { - return %commands; - } else { - return %files; - } - -} - -sub load_command_lines -{ - my $lab_scripts_path = $_[0]; - my $lab_scripts_mask = $_[1]; - - my $cline_re_base = qq' - (?:\\^?([0-9]*C?)) # exitcode - (?:_([0-9]+)_)? # uid - (?:_([0-9]+)_) # pid - (...?) # day - (.?.?) # lab - \\s # space separator - ([0-9][0-9]):([0-9][0-9]):([0-9][0-9]) # time - .\\[50D.\\[K # killing symbols - (.*?([\$\#]\\s?)) # prompt - (.*) # command line - '; - #my $cline_re = qr/$cline_re_base(?:$cline_re_base|$)/x; - #my $cline_re = qr/(?:$cline_re_base)*$cline_re_base$/x; - my $cline_re = qr/$cline_re_base/sx; - my $cline_re1 = qr/$cline_re_base\x0D/sx; - my $cline_re2 = qr/$cline_re_base$/sx; - - my $vt = Term::VT102->new ( 'cols' => $Config{"terminal_width"}, - 'rows' => $Config{"terminal_height"}); - my $cline_vt = Term::VT102->new ('cols' => $Config{"terminal_width"}, - 'rows' => $Config{"terminal_height"}); - - my $converter = Text::Iconv->new($Config{"encoding"}, "utf-8") - if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i); - - print "Loading lm-scripts...\n" if $Config{"verbose"} =~ /y/; - - my @lab_scripts = <$lab_scripts_path/$lab_scripts_mask>; - my $file; - my $files_number = $#lab_scripts; - my $ii = 0; - my $skip_info; - - my $commandlines_loaded =0; - my $commandlines_processed =0; - - for $file (@lab_scripts){ - #printf "\t%i %3.2f\n", $ii, (100*$ii++/$files_number) if $Config{"verbose"} =~ /y/; - - open (FILE, "$file"); - binmode FILE; - $file =~ m@.*/(.*?)-.*@; - - my $tty = $1; - my $first_pass = 1; - my %cl; - my $last_output_length=0; - while () { - $commandlines_processed++; - # time - - if (/[0-9][0-9]:[0-9][0-9]:[0-9][0-9].\[[0-9][0-9]D.\[K/ && m/$cline_re/) { - s/.*\x0d(?!\x0a)//; - # print "!!!",$_,"!!!\n"; - # next; - # while (m/$cline_re1/gs) { - # } - m/$cline_re2/gs; - - $commandlines_loaded++; - $last_output_length=0; - - # Previous command - my %last_cl = %cl; - my $err = $1 || ""; - - -=cut - -ТАБЛИЦА КОМАНД - - uid - Идентификатор пользователя - - tty - Идентификатор терминала, на котором была вызвана команда - - pid - PID-процесса командного интерпретатора, - в котором была вызвана команда - - lab - лабораторная работа, к которой относится команда. - Идентификатор текущей лабораторной работы - хранится в файле ~/.labmaker/lab - - pwd (!) - текущий каталог, из которого была вызвана команда - - day - время вызова, день - В действительности здесь хранится не время вызова команды, - а с момента появления приглашения командного интерпретатора - для ввода команды - - - hour - время вызова, час - - min - время вызова, минута - - sec - время вызова, секунда - - time (!) - время вызова команды в Unix-формате. - Предпочтительнее использовать этот формат чем hour:min:sec, - использовавшийся в Labmaker - - fullprompt - Приглашение командной строки - - prompt - Сокращённое приглашение командной строки - - cline - Командная строка - - output - Результат выполнения команды - - diff - Указатель на ассоциированный с командой diff - - note (!) - Текстовый комментарий к команде. - Может генерироваться из самого лога с помощью команд - #^ Комментарий - #v Комментарий - в том случае, если для комментирования достаточно одной строки, - или с помощью команд - cat > /dev/null #^ Заголовок - Текст - ^D - в том случае, если комментарий развёрнутый. - В последнем случае комментарий может содержать - заголовок, абзацы и несложное форматирование. - - Символ ^ или v после знака комментария # обозначает, - к какой команде относится комментарий: - к предыдущей (^) или последующей (v) - - err - Код завершения командной строки - - histnum (!) - Номер команды в истории командного интерпретатора - - status (!) - Является ли данная команда вызванной (r), запомненной (s) - или это подсказка completion (c). - - Команды, которые были вызваны и обработаны интерпретатором - имеют состояние "r". К таким командам относится большинство - команд вводимых в интерпретатор. - - Если команда набрана, но вызывать её по какой-либо причине - не хочется (например, команда может быть не полной, вредоносной - или просто бессмысленной в текущих условиях), - её можно сбросить с помощью комбинации клавиш Ctrl-C - (не путайте с прерыванием работающей команды! здесь она даже - не запускается!). - В таком случае она не выполняется, но попадает в журнал - со статусом "s". - - Если команда появилась в журнале благодаря автопроолжению - -- когда было показано несколько вариантов -- - она имеет статус "c". - - euid - Идентификатор пользователя от имени которого будет - выполняться команда. - Может отличаться от реального uid в том случае, - если вызывается с помощью sudo - - - version (!) - Версия lilalo-prompt использовавшаяся при записи - команды. - - 0 - версия использовавшая в labmaker. - Отсутствует информация о текущем каталоге и номере в истории. - Информация о версии также не указана в приглашении. - - - 1 - версия использующаяся в lilalo - - raw_file (*) - Имя файла, в котором находится бинарное представление журнала. - Может содержать ключевое слово HERE, - обозначающее что бинарное представление хранится - непосредственно в базе данных в атрибуте raw_data - - raw_start (*) - Начало блока командной строки в файле бинарного представления - - raw_end (*) - Конец блока командной строки в файле бинарного представления - - raw_cline (*) - Необработанная командная строка в бинарном виде - - raw_data (*) - Бинарное представление команды и результатов её выполнения - - - - -ТАБЛИЦА SESSION - - Информация о сеансах - - - - -=cut - - # Parse new command - $cl{"uid"} = $2; - $cl{"euid"} = $cl{"uid"}; # Если в команде обнаружится sudo, euid поменяем на 0 - $cl{"pid"} = $3; - $cl{"day"} = $4; - $cl{"lab"} = $5; - $cl{"hour"} = $6; - $cl{"min"} = $7; - $cl{"sec"} = $8; - $cl{"fullprompt"} = $9; - $cl{"prompt"} = $10; - $cl{"raw_cline"} = $11; - - $cl{"err"} = 0; - $cl{"output"} = ""; - $cl{"tty"} = $tty; - - $cline_vt->process($cl{"raw_cline"}."\n"); - $cl{"cline"} = $cline_vt->row_plaintext (1); - $cl{"cline"} =~ s/\s*$//; - $cline_vt->reset(); - - my %commands = extract_from_cline("commands", $cl{"cline"}); - $cl{"euid"}=0 if defined $commands{"sudo"}; - my @comms = sort { $commands{$a} cmp $commands{$b} } keys %commands; - $cl{"last_command"} = $comms[$#comms] || ""; - - if ( - $Config{"suppress_editors"} =~ /^y/i - && grep ($_ eq $cl{"last_command"}, @{$Config{"editors"}}) || - $Config{"suppress_pagers"} =~ /^y/i - && grep ($_ eq $cl{"last_command"}, @{$Config{"pagers"}}) || - $Config{"suppress_terminal"}=~ /^y/i - && grep ($_ eq $cl{"last_command"}, @{$Config{"terminal"}}) - ) { - $cl{"suppress_output"} = "1"; - } - else { - $cl{"suppress_output"} = "0"; - - } - $skip_info = 0; - - - print " ",$cl{"last_command"}; - - # Processing previous command line - if ($first_pass) { - $first_pass = 0; - next; - } - - # Error code - $last_cl{"err"}=$err; - $last_cl{"err"}=130 if $err eq "^C"; - - if (grep ($_ eq $last_cl{"last_command"}, @{$Config{"editors"}})) { - bind_diff(\%last_cl); - } - - # Output - if (!$last_cl{"suppress_output"} || $last_cl{"err"}) { - for (my $i=0; $i<$Config{"terminal_height"}; $i++) { - my $line= $vt->row_plaintext($i); - next if !defined ($line) || $line =~ /^\s*$/; - $line =~ s/\s*$//; - $last_cl{"output"} .= $line."\n"; - } - } - else { - $last_cl{"output"}= ""; - } - - $vt->reset(); - - - # Classifying the command line - - - # Save - if (!$Config{"lab"} || $cl{"lab"} eq $Config{"lab"}) { - # Changing encoding - for (keys %last_cl) { - $last_cl{$_} = $converter->convert($last_cl{$_}) - if ($Config{"encoding"} && - $Config{"encoding"} !~ /^utf-8$/i); - } - push @Command_Lines, \%last_cl; - } - next; - } - $last_output_length+=length($_); - #if (!$cl{"suppress_output"} || $last_output_length < 5000) { - if ($last_output_length < 50000) { - #print "(",length($_),")" if (length($_) > 2000) ; - $vt->process("$_"."\n") - } - else - { - if (!$skip_info) { - print "($cl{last_command})"; - $skip_info = 1; - } - } - } - close(FILE); - - } - if ($Config{"verbose"} =~ /y/) { - print "...finished." ; - print "Lines loaded: $commandlines_processed\n"; - print "Command lines: $commandlines_loaded\n"; - } -} - -sub search_by -{ - my $sm = shift; - my $topic = shift; - $topic =~ s/ /+/; - - return ""; -} - -sub make_comment -{ - my $commands = $_[0]; - my $files = $_[1]; - chomp $commands; - chomp $files; - return if (!$commands && !$files); - - my $comment=""; - - # Commands - for my $command (split /\s+/,$commands) { - $command =~ s/'//g; - my $description=""; - eval { $description=`mywi-client '$command'`; } ; - $description = join ("
\n", grep(/\([18]\)/, split(/\n/, $description))); - $description =~ s/.*?-//; - next if $description =~ /^\s*$/; - - my $query=$command." ".$Config{"keywords"}; - $query =~ s/\ /+/g; - my $search= search_by("opennet",$query). - search_by("local",$command). - search_by("google",$query); - - $comment .= "
". - "". - ""; - } - - # Files - for my $file (split /\s+/,$files) { - $file =~ s@.*/@@; - $file =~ s/'//g; - next if $file =~ /^\s*$/; - next if $file =~ /^-/; - - my $description=`mywi '$file'`; - $description = join ("
\n", grep(/\(5\)/, split(/\n/, $description))); - next if $description =~ /^\s*$/; - - my $query=$file." ".$Config{"files_keywords"}; - $query =~ s/\ /+/g; - my $search= search_by("opennet",$query). - search_by("local",$file). - search_by("google",$query); - - $comment .= "". - "". - ""; - } - - - return $comment; -} - -sub printq -{ - my $TO = shift; - my $text = join "", @_; - $text =~ s/&/&/g; - $text =~ s//>/g; - print $TO $text; -} - - -sub sort_command_lines -{ - print "Sorting command lines...\n" if $Config{"verbose"} =~ /y/; - - # Sort Command_Lines - # Write Command_Lines to Command_Lines_Index - - my @index; - for (my $i=0;$i<=$#Command_Lines;$i++) { - $index[$i]=$i; - } - - @Command_Lines_Index = sort { - $Command_Lines[$index[$a]]->{"day"} cmp $Command_Lines[$index[$b]]->{"day"} || - $Command_Lines[$index[$a]]->{"hour"} <=> $Command_Lines[$index[$b]]->{"hour"} || - $Command_Lines[$index[$a]]->{"min"} <=> $Command_Lines[$index[$b]]->{"min"} || - $Command_Lines[$index[$a]]->{"sec"} <=> $Command_Lines[$index[$b]]->{"sec"} - } @index; - - print "...finished\n" if $Config{"verbose"} =~ /y/; - -} - -sub process_command_lines -{ - my $lab_scripts_path = $_[0]; - - for my $i (@Command_Lines_Index) { - - my $cl = \$Command_Lines[$i]; - @{${$cl}->{"new_commands"}} =(); - @{${$cl}->{"new_files"}} =(); - $$cl->{"class"} = ""; - - if ($$cl->{"err"}) { - $$cl->{"class"}="wrong"; - $$cl->{"class"}="interrupted" - if ($$cl->{"err"} eq 130); - } - if (!$$cl->{"euid"}) { - $$cl->{"class"}.="_root"; - } - -#tab# my @tab_words=split /\s+/, $$cl->{"output"}; -#tab# my $last_word= $$cl->{"cline"} =~ /(\S*)$/; -#tab# $last_word =~ s@.*/@@; -#tab# my $this_is_tab=1; -#tab# -#tab# if ($last_word && @tab_words >2) { -#tab# for my $tab_words (@tab_words) { -#tab# if ($tab_words !~ /^$last_word/) { -#tab# $this_is_tab=0; -#tab# last; -#tab# } -#tab# } -#tab# } -#tab# $$cl->{"class"}="tab" if $this_is_tab; - - - if ( !$$cl->{"err"}) { - # Command does not contain mistakes - - my %commands = extract_from_cline("commands", ${$cl}->{"cline"}); - my %files = extract_from_cline("files", ${$cl}->{"cline"}); - - # Searching for new commands only - for my $command (keys %commands) { - if (!defined $Commands_Stat{$command}) { - push @{$$cl->{new_commands}}, $command; - } - $Commands_Stat{$command}++; - } - - for my $file (keys %files) { - if (!defined $Files_Stat{$file}) { - push @{$$cl->{new_files}}, $file; - } - $Files_Stat{$file}++; - } - } - } - -} - - -=cut -Вывести результат обработки журнала. -=cut - - -sub print_command_lines -{ - my $output_filename=$_[0]; - my $format = $Config{"output_format"}; - - my $course_name = $Config{"course-name"}; - my $course_code = $Config{"course-code"}; - my $course_date = $Config{"course-date"}; - my $course_center = $Config{"course-center"}; - my $course_trainer = $Config{"course-trainer"}; - my $course_student = $Config{"course-student"}; - - open(OUT, ">", $output_filename) - or die "Can't open $output_filename for writing\n"; - - - - if ($format eq "html") { - # vvvv HTML Header - print OUT < - - - - - - -

Журнал лабораторных работ

- -

- Выполнил $course_student
- Проверил $course_trainer
- Курс $course_name ($course_code), - $course_date
- Учебный центр $course_center
-

- - - -

Журнал

-HEADER - print OUT "
",$student->{"firstname"}," ",$student->{"surname"},"",$hostname,"",$user,"","root","
$command
". - "$description
$file
". - "$description
\n"; - for my $element (keys %Elements_Visibility) - { - my @e = split /\s+/, $element; - my $showhide = join "", map { "ShowHide('$_');" } @e ; - print OUT "", - $Elements_Visibility{$element}, - "
\n"; - } - #print OUT "". - #"
\n"; - #print OUT "". - #"
\n"; - - print OUT "
\n"; - print OUT "\n"; - # ^^^^ HTML Header - } - else { - # XML Header - print OUT "\n"; - } - close(OUT); -} - -sub read_config_file -{ - my $config = $_[0]; - my $filename = $_[1]; - open(CONFIG, "$filename") - or return; - while () { - s/#.*//; - next if /^\s*$/; - my ($var, $val) = split /\s*=\s*/, $_, 2; - $var =~ s/\s*//; - $config->{$var} = $val; - } - close(CONFIG); -} - - -sub print_command_lines2 -{ - my $output_filename=$_[0]; - open(OUT, ">", $output_filename) - or die "Can't open $output_filename for writing\n"; - - - print OUT < -OUT - - my $cl; - for my $i (@Command_Lines_Index) { - - - $cl = $Command_Lines[$i]; - - -# Printing out - print OUT < - $cl->{day} - $cl->{hour} - $cl->{min} - $cl->{sec} - $cl->{tty} - $cl->{uid} - $cl->{euid} - $cl->{prompt} - $cl->{cline} - $cl->{err} - -$cl->{output} - -OUT - } - - for my $diff (@Diffs) { - - print OUT < - $diff->{path} - $diff->{uid} - $diff->{day} - $diff->{hour} - $diff->{min} - $diff->{sec} - -$diff->{text} - -OUT - } - - print OUT < -OUT -} - - -$| = 1; - -my %file_config; -my %argv_config; -init_variables; -read_config_file(\%file_config, $Config_File); -GetOptions(\%argv_config, map "$_=s", keys %Config); -%Config = (%Config, %file_config, %argv_config); - -my $i=0; - -for my $lab_log (split (/\s+/, $Config{"diffs"} || $Config{"input"})) -{ - load_diff_files($lab_log); -} - -for my $lab_log (split /\s+/, $Config{"input"}) -{ - my $tofile=$Config{"output"}; - $tofile =~ s/$Config{"output_mask"}/$i/; - #load_diff_files($lab_log); - load_command_lines($lab_log, $Config{"input_mask"}); - sort_command_lines; - process_command_lines($lab_log); - print_command_lines($tofile); - $i++; -} - - diff -r 93e08c4b54ed -r f9d0d35618f8 lm-ssh --- a/lm-ssh Mon Jul 21 11:24:53 2008 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -#!/bin/sh -#\ -exec expect -- "$0" ${1+"$@"} -eval spawn ssh $argv -set timeout 1 -expect { - eof { - } - "(yes/no)? " { - send "yes\n" - exp_continue - } - assword: { - send "rootpass\n" - } - timeout { - interact -nobuffer - } -} -expect { - eof { - } - assword: { - send "rootpass\n" - } - - timeout { - interact -nobuffer - } -} - diff -r 93e08c4b54ed -r f9d0d35618f8 taillast.pl --- a/taillast.pl Mon Jul 21 11:24:53 2008 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#!/usr/bin/perl - -for $d (@ARGV) { - push @d, glob("$d/*"); -} -@{f} = sort { (stat(${a}))[9] <=> (stat(${b}))[9] } (@d); -print "tail -f ${f[$#f]}\n"; -__END__