lilalo

annotate lm-report @ 100:2c00c61f2d7b

Коммичу изменения, но сам не знаю зачем.
Нужно l3-cgi переписать вообще с нуля.
Он мерзкий.

И продумать нужно, как он вообще должен работать.
Понятно, приблизительно, как он должен показывать журнал,
когда до него уже дошли,
но вот если не дошли, то что делать не понятно.
Короче, продумать систему навигации.
author devi
date Wed Jun 14 21:37:22 2006 +0300 (2006-06-14)
parents ab8d2a28fc86
children
rev   line source
devi@0 1 #!/usr/bin/perl -w
devi@0 2
devi@0 3 #
devi@20 4 # (c) Igor Chubin, imchubin@mail.ru, 2004-2005
devi@0 5 #
devi@0 6
devi@0 7 use strict;
devi@0 8 use Getopt::Long;
devi@0 9 use Term::VT102;
devi@0 10 use Text::Iconv;
devi@0 11 use Data::Dumper;
devi@0 12
devi@0 13 our $Config_File = "labmaker.conf";
devi@0 14 our %Config = (
devi@0 15 "skip_empty" => "yes",
devi@0 16 "skip_interrupted" => "no",
devi@0 17 "skip_wrong" => "no",
devi@0 18 "editors" => ["vi", "pico", "ee", "vim"],
devi@0 19 "pagers" => ["more", "less", "zmore", "zless", "info",
devi@0 20 "man", "mc", "trafshow", "screen", "cfdisk",
devi@0 21 "trafshow-bsd", "yes", "lynx", "links", "centericq"
devi@0 22 ],
devi@0 23 "terminal" => ["mc"],
devi@0 24 "suppress_editors" => "yes",
devi@0 25 "suppress_pagers" => "yes",
devi@0 26 "suppress_terminal" => "yes",
devi@0 27
devi@0 28 "terminal_width" => 100,
devi@0 29 "terminal_height" => 100,
devi@0 30 "verbose" => "yes",
devi@0 31
devi@0 32 "head_lines" => 5,
devi@0 33 "tail_lines" => 5,
devi@0 34 "skip_text" => "...",
devi@0 35 "show_time" => "yes",
devi@0 36 "show_diffs" => "yes",
devi@0 37 "show_comments" => "yes",
devi@0 38
devi@0 39 "input" => "/root/.labmaker",
devi@0 40 "diffs" => "",
devi@0 41 "input_mask" => "*.script",
devi@0 42 "encoding" => "utf-8",
devi@0 43
devi@0 44 "output" => "/var/www/lm/reportINDEX.html",
devi@0 45 #"output" => "report.xml",
devi@0 46 "output_mask" => "INDEX",
devi@0 47 "output_format" => "html",
devi@0 48
devi@0 49 "signature" => "#lm:",
devi@0 50 "from" => "",
devi@0 51 "to" => "",
devi@0 52 "lab" => "",
devi@0 53 "keywords" => "linux command",
devi@0 54 "files_keywords" => "linux file",
devi@0 55
devi@0 56 comment_width => "300",
devi@0 57 time_width => "60",
devi@0 58
devi@6 59 "course-name" => "",
devi@6 60 "course-code" => "",
devi@6 61 "course-date" => "",
devi@6 62 "course-center" => "",
devi@6 63 "course-trainer" => "",
devi@6 64 "course-student" => "",
devi@6 65
devi@0 66 );
devi@0 67
devi@0 68 our @Command_Lines;
devi@0 69 our @Command_Lines_Index;
devi@0 70 our @Diffs;
devi@0 71
devi@0 72 our %Commands_Stat; # Statistics about commands usage
devi@0 73 our %Files_Stat; # Statistics about commands usage
devi@0 74
devi@0 75 our %Search_Machines = (
devi@0 76 "google" => { "query" => "http://www.google.com/search?q=" ,
devi@0 77 "icon" => "google.ico" },
devi@0 78 "freebsd" => { "query" => "http://www.freebsd.org/cgi/man.cgi?query=",
devi@0 79 "icon" => "freebsd.ico" },
devi@0 80 "linux" => { "query" => "http://man.he.net/?topic=",
devi@0 81 "icon" => "linux.ico"},
devi@0 82 "opennet" => { "query" => "http://www.opennet.ru/search.shtml?words=",
devi@0 83 "icon" => "opennet.ico"},
devi@0 84 "local" => { "query" => "http://www.freebsd.org/cgi/man.cgi?query=",
devi@0 85 "icon" => "freebsd.ico" },
devi@0 86
devi@0 87 );
devi@0 88
devi@0 89 our %Elements_Visibility = (
devi@0 90 "note" => "замечания",
devi@0 91 "diff" => "редактор",
devi@0 92 "time" => "время",
devi@0 93 "ttychange" => "терминал",
devi@0 94 "wrong_output wrong_cline wrong_root_output wrong_root_cline"
devi@0 95 => "команды с ошибками",
devi@0 96 "interrupted_output interrupted_cline interrupted_root_output interrupted_root_cline"
devi@0 97 => "прерванные команды",
devi@0 98 "tab_completion_output tab_completion_cline"
devi@0 99 => "продолжение с помощью tab"
devi@0 100 );
devi@0 101
devi@6 102 sub init_variables;
devi@6 103 our $Html_Help;
devi@6 104 our $Html_About;
devi@6 105
devi@0 106
devi@0 107 sub load_diff_files
devi@0 108 {
devi@0 109 my @pathes = @_;
devi@0 110
devi@0 111 for my $path (@pathes) {
devi@0 112 my $template = "*.diff";
devi@0 113 my @files = <$path/$template>;
devi@0 114 my $i=0;
devi@0 115 for my $file (@files) {
devi@0 116 my %diff;
devi@0 117
devi@0 118 $diff{"path"}=$path;
devi@0 119 $diff{"uid"}="SET THIS";
devi@0 120
devi@0 121 # Сейчас UID определяется из названия каталога
devi@0 122 # откуда берутся diff-файлы
devi@0 123 # Это неправильно
devi@0 124 #
devi@0 125 # ВАРИАНТ:
devi@0 126 # К файлам жураналам должны прилагаться ситемны файлы,
devi@0 127 # мз которых и будет определяться соответствие
devi@0 128 # имён пользователей их uid'ам
devi@0 129 #
devi@0 130 $diff{"uid"} = 0 if $path =~ m@/root/@;
devi@0 131
devi@0 132 $diff{"bind_to"}="";
devi@0 133 $diff{"time_range"}=-1;
devi@0 134
devi@0 135 next if not $file=~m@/(D?[0-9][0-9]?[0-9]?)[^/]*?([0-9]*):([0-9]*):?([0-9]*)@;
devi@0 136 $diff{"day"}=$1 || "";
devi@0 137 $diff{"hour"}=$2;
devi@0 138 $diff{"min"}=$3;
devi@0 139 $diff{"sec"}=$4 || 0;
devi@0 140
devi@0 141 $diff{"index"}=$i;
devi@0 142
devi@0 143 print "diff loaded: $diff{day} $diff{hour}:$diff{min}:$diff{sec}\n";
devi@0 144
devi@0 145 local $/;
devi@0 146 open (F, "$file")
devi@0 147 or return "Can't open file $file ($_[0]) for reading";
devi@0 148 my $text = <F>;
devi@0 149 if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i) {
devi@0 150 my $converter = Text::Iconv->new($Config{"encoding"}, "utf-8");
devi@0 151 $text = $converter->convert($text);
devi@0 152 }
devi@0 153 close(F);
devi@0 154 $diff{"text"}=$text;
devi@0 155 #print "$file loaded ($diff{day})\n";
devi@0 156
devi@0 157 push @Diffs, \%diff;
devi@0 158 $i++;
devi@0 159 }
devi@0 160 }
devi@0 161 }
devi@0 162
devi@0 163
devi@0 164 sub bind_diff
devi@0 165 {
devi@0 166 # my $path = shift;
devi@0 167 # my $pid = shift;
devi@0 168 # my $day = shift;
devi@0 169 # my $lab = shift;
devi@0 170
devi@0 171 print "Trying to bind diff...\n";
devi@0 172
devi@0 173 my $cl = shift;
devi@0 174 my $hour = $cl->{"hour"};
devi@0 175 my $min = $cl->{"min"};
devi@0 176 my $sec = $cl->{"sec"};
devi@0 177
devi@0 178 my $min_dt = 10000;
devi@0 179
devi@0 180 for my $diff (@Diffs) {
devi@0 181 # Check here date, time and user
devi@0 182 next if ($diff->{"day"} && $cl->{"day"} && ($cl->{"day"} ne $diff->{"day"}));
devi@0 183 #next if (!$diff->{"uid"} && $cl->{"euid"} != $diff->{"uid"});
devi@0 184
devi@0 185 my $dt=($diff->{"hour"}-$hour)*3600 +($diff->{"min"}-$min)*60 + ($diff->{"sec"}-$sec);
devi@0 186 if ($dt >0 && $dt < $min_dt && ($diff->{"time_range"} <0 || $dt < $diff->{"time_range"})) {
devi@0 187 print "Approppriate diff found: dt=$dt\n";
devi@0 188 if ($diff->{"bind_to"}) {
devi@0 189 undef $diff->{"bind_to"}->{"diff"};
devi@0 190 };
devi@0 191 $diff->{"time_range"}=$dt;
devi@0 192 $diff->{"bind_to"}=$cl;
devi@0 193
devi@0 194 $cl->{"diff"} = $diff->{"index"};
devi@0 195 $min_dt = $dt;
devi@0 196 }
devi@0 197
devi@0 198 }
devi@0 199 }
devi@0 200
devi@0 201
devi@0 202 sub extract_from_cline
devi@0 203 # Разобрать командную строку $_[1] и возвратить хэш, содержащий
devi@0 204 # номер первого появление команды в строке:
devi@0 205 # команда => первая позиция
devi@0 206 {
devi@0 207 my $what = $_[0];
devi@0 208 my $cline = $_[1];
devi@0 209 my @lists = split /\;/, $cline;
devi@0 210
devi@0 211
devi@0 212 my @commands = ();
devi@0 213 for my $list (@lists) {
devi@0 214 push @commands, split /\|/, $list;
devi@0 215 }
devi@0 216
devi@0 217 my %commands;
devi@0 218 my %files;
devi@0 219 my $i=0;
devi@0 220 for my $command (@commands) {
devi@0 221 $command =~ /\s*(\S+)\s*(.*)/;
devi@0 222 if ($1 && $1 eq "sudo" ) {
devi@0 223 $commands{"$1"}=$i++;
devi@0 224 $command =~ s/\s*sudo\s+//;
devi@0 225 }
devi@0 226 $command =~ /\s*(\S+)\s*(.*)/;
devi@0 227 if ($1 && !defined $commands{"$1"}) {
devi@0 228 $commands{"$1"}=$i++;
devi@0 229 };
devi@0 230 if ($2) {
devi@0 231 my $args = $2;
devi@0 232 my @args = split (/\s+/, $args);
devi@0 233 for my $a (@args) {
devi@0 234 $files{"$a"}=$i++
devi@0 235 if !defined $files{"$a"};
devi@0 236 };
devi@0 237
devi@0 238
devi@0 239 }
devi@0 240 }
devi@0 241
devi@0 242 if ($what eq "commands") {
devi@0 243 return %commands;
devi@0 244 } else {
devi@0 245 return %files;
devi@0 246 }
devi@0 247
devi@0 248 }
devi@0 249
devi@0 250 sub load_command_lines
devi@0 251 {
devi@0 252 my $lab_scripts_path = $_[0];
devi@0 253 my $lab_scripts_mask = $_[1];
devi@0 254
devi@0 255 my $cline_re_base = qq'
devi@0 256 (?:\\^?([0-9]*C?)) # exitcode
devi@0 257 (?:_([0-9]+)_)? # uid
devi@0 258 (?:_([0-9]+)_) # pid
devi@0 259 (...?) # day
devi@19 260 (.?.?) # lab
devi@0 261 \\s # space separator
devi@0 262 ([0-9][0-9]):([0-9][0-9]):([0-9][0-9]) # time
devi@0 263 .\\[50D.\\[K # killing symbols
devi@0 264 (.*?([\$\#]\\s?)) # prompt
devi@0 265 (.*) # command line
devi@0 266 ';
devi@0 267 #my $cline_re = qr/$cline_re_base(?:$cline_re_base|$)/x;
devi@0 268 #my $cline_re = qr/(?:$cline_re_base)*$cline_re_base$/x;
devi@0 269 my $cline_re = qr/$cline_re_base/sx;
devi@0 270 my $cline_re1 = qr/$cline_re_base\x0D/sx;
devi@0 271 my $cline_re2 = qr/$cline_re_base$/sx;
devi@0 272
devi@0 273 my $vt = Term::VT102->new ( 'cols' => $Config{"terminal_width"},
devi@0 274 'rows' => $Config{"terminal_height"});
devi@0 275 my $cline_vt = Term::VT102->new ('cols' => $Config{"terminal_width"},
devi@0 276 'rows' => $Config{"terminal_height"});
devi@0 277
devi@0 278 my $converter = Text::Iconv->new($Config{"encoding"}, "utf-8")
devi@0 279 if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i);
devi@0 280
devi@0 281 print "Loading lm-scripts...\n" if $Config{"verbose"} =~ /y/;
devi@0 282
devi@0 283 my @lab_scripts = <$lab_scripts_path/$lab_scripts_mask>;
devi@0 284 my $file;
devi@0 285 my $files_number = $#lab_scripts;
devi@0 286 my $ii = 0;
devi@0 287 my $skip_info;
devi@0 288
devi@0 289 my $commandlines_loaded =0;
devi@0 290 my $commandlines_processed =0;
devi@0 291
devi@0 292 for $file (@lab_scripts){
devi@0 293 #printf "\t%i %3.2f\n", $ii, (100*$ii++/$files_number) if $Config{"verbose"} =~ /y/;
devi@0 294
devi@0 295 open (FILE, "$file");
devi@0 296 binmode FILE;
devi@0 297 $file =~ m@.*/(.*?)-.*@;
devi@0 298
devi@0 299 my $tty = $1;
devi@0 300 my $first_pass = 1;
devi@0 301 my %cl;
devi@0 302 my $last_output_length=0;
devi@0 303 while (<FILE>) {
devi@0 304 $commandlines_processed++;
devi@0 305 # time
devi@0 306
devi@0 307 if (/[0-9][0-9]:[0-9][0-9]:[0-9][0-9].\[[0-9][0-9]D.\[K/ && m/$cline_re/) {
devi@0 308 s/.*\x0d(?!\x0a)//;
devi@0 309 # print "!!!",$_,"!!!\n";
devi@0 310 # next;
devi@0 311 # while (m/$cline_re1/gs) {
devi@0 312 # }
devi@0 313 m/$cline_re2/gs;
devi@0 314
devi@0 315 $commandlines_loaded++;
devi@0 316 $last_output_length=0;
devi@0 317
devi@0 318 # Previous command
devi@0 319 my %last_cl = %cl;
devi@0 320 my $err = $1 || "";
devi@0 321
devi@21 322
devi@21 323 =cut
devi@21 324
devi@21 325 ТАБЛИЦА КОМАНД
devi@21 326
devi@21 327 uid
devi@21 328 Идентификатор пользователя
devi@21 329
devi@21 330 tty
devi@21 331 Идентификатор терминала, на котором была вызвана команда
devi@21 332
devi@21 333 pid
devi@21 334 PID-процесса командного интерпретатора,
devi@21 335 в котором была вызвана команда
devi@21 336
devi@21 337 lab
devi@21 338 лабораторная работа, к которой относится команда.
devi@21 339 Идентификатор текущей лабораторной работы
devi@21 340 хранится в файле ~/.labmaker/lab
devi@21 341
devi@21 342 pwd (!)
devi@21 343 текущий каталог, из которого была вызвана команда
devi@21 344
devi@21 345 day
devi@21 346 время вызова, день
devi@21 347 В действительности здесь хранится не время вызова команды,
devi@21 348 а с момента появления приглашения командного интерпретатора
devi@21 349 для ввода команды
devi@21 350
devi@21 351
devi@21 352 hour
devi@21 353 время вызова, час
devi@21 354
devi@21 355 min
devi@21 356 время вызова, минута
devi@21 357
devi@21 358 sec
devi@21 359 время вызова, секунда
devi@21 360
devi@21 361 time (!)
devi@21 362 время вызова команды в Unix-формате.
devi@21 363 Предпочтительнее использовать этот формат чем hour:min:sec,
devi@21 364 использовавшийся в Labmaker
devi@21 365
devi@21 366 fullprompt
devi@21 367 Приглашение командной строки
devi@21 368
devi@21 369 prompt
devi@21 370 Сокращённое приглашение командной строки
devi@21 371
devi@21 372 cline
devi@21 373 Командная строка
devi@21 374
devi@21 375 output
devi@21 376 Результат выполнения команды
devi@21 377
devi@21 378 diff
devi@21 379 Указатель на ассоциированный с командой diff
devi@21 380
devi@21 381 note (!)
devi@21 382 Текстовый комментарий к команде.
devi@21 383 Может генерироваться из самого лога с помощью команд
devi@21 384 #^ Комментарий
devi@21 385 #v Комментарий
devi@21 386 в том случае, если для комментирования достаточно одной строки,
devi@21 387 или с помощью команд
devi@21 388 cat > /dev/null #^ Заголовок
devi@21 389 Текст
devi@21 390 ^D
devi@21 391 в том случае, если комментарий развёрнутый.
devi@21 392 В последнем случае комментарий может содержать
devi@21 393 заголовок, абзацы и несложное форматирование.
devi@21 394
devi@21 395 Символ ^ или v после знака комментария # обозначает,
devi@21 396 к какой команде относится комментарий:
devi@21 397 к предыдущей (^) или последующей (v)
devi@21 398
devi@21 399 err
devi@21 400 Код завершения командной строки
devi@21 401
devi@21 402 histnum (!)
devi@21 403 Номер команды в истории командного интерпретатора
devi@21 404
devi@21 405 status (!)
devi@21 406 Является ли данная команда вызванной (r), запомненной (s)
devi@21 407 или это подсказка completion (c).
devi@21 408
devi@21 409 Команды, которые были вызваны и обработаны интерпретатором
devi@21 410 имеют состояние "r". К таким командам относится большинство
devi@21 411 команд вводимых в интерпретатор.
devi@21 412
devi@21 413 Если команда набрана, но вызывать её по какой-либо причине
devi@21 414 не хочется (например, команда может быть не полной, вредоносной
devi@21 415 или просто бессмысленной в текущих условиях),
devi@21 416 её можно сбросить с помощью комбинации клавиш Ctrl-C
devi@21 417 (не путайте с прерыванием работающей команды! здесь она даже
devi@21 418 не запускается!).
devi@21 419 В таком случае она не выполняется, но попадает в журнал
devi@21 420 со статусом "s".
devi@21 421
devi@21 422 Если команда появилась в журнале благодаря автопроолжению
devi@21 423 -- когда было показано несколько вариантов --
devi@21 424 она имеет статус "c".
devi@21 425
devi@21 426 euid
devi@21 427 Идентификатор пользователя от имени которого будет
devi@21 428 выполняться команда.
devi@21 429 Может отличаться от реального uid в том случае,
devi@21 430 если вызывается с помощью sudo
devi@21 431
devi@21 432
devi@21 433 version (!)
devi@21 434 Версия lilalo-prompt использовавшаяся при записи
devi@21 435 команды.
devi@21 436
devi@21 437 0 - версия использовавшая в labmaker.
devi@21 438 Отсутствует информация о текущем каталоге и номере в истории.
devi@21 439 Информация о версии также не указана в приглашении.
devi@21 440
devi@21 441
devi@21 442 1 - версия использующаяся в lilalo
devi@21 443
devi@21 444 raw_file (*)
devi@21 445 Имя файла, в котором находится бинарное представление журнала.
devi@21 446 Может содержать ключевое слово HERE,
devi@21 447 обозначающее что бинарное представление хранится
devi@21 448 непосредственно в базе данных в атрибуте raw_data
devi@21 449
devi@21 450 raw_start (*)
devi@21 451 Начало блока командной строки в файле бинарного представления
devi@21 452
devi@21 453 raw_end (*)
devi@21 454 Конец блока командной строки в файле бинарного представления
devi@21 455
devi@21 456 raw_cline (*)
devi@21 457 Необработанная командная строка в бинарном виде
devi@21 458
devi@21 459 raw_data (*)
devi@21 460 Бинарное представление команды и результатов её выполнения
devi@21 461
devi@21 462
devi@21 463
devi@21 464
devi@21 465 ТАБЛИЦА SESSION
devi@21 466
devi@21 467 Информация о сеансах
devi@21 468
devi@21 469
devi@21 470
devi@21 471
devi@21 472 =cut
devi@21 473
devi@0 474 # Parse new command
devi@0 475 $cl{"uid"} = $2;
devi@0 476 $cl{"euid"} = $cl{"uid"}; # Если в команде обнаружится sudo, euid поменяем на 0
devi@0 477 $cl{"pid"} = $3;
devi@0 478 $cl{"day"} = $4;
devi@0 479 $cl{"lab"} = $5;
devi@0 480 $cl{"hour"} = $6;
devi@0 481 $cl{"min"} = $7;
devi@0 482 $cl{"sec"} = $8;
devi@0 483 $cl{"fullprompt"} = $9;
devi@0 484 $cl{"prompt"} = $10;
devi@0 485 $cl{"raw_cline"} = $11;
devi@0 486
devi@0 487 $cl{"err"} = 0;
devi@0 488 $cl{"output"} = "";
devi@0 489 $cl{"tty"} = $tty;
devi@0 490
devi@0 491 $cline_vt->process($cl{"raw_cline"}."\n");
devi@0 492 $cl{"cline"} = $cline_vt->row_plaintext (1);
devi@0 493 $cl{"cline"} =~ s/\s*$//;
devi@0 494 $cline_vt->reset();
devi@0 495
devi@0 496 my %commands = extract_from_cline("commands", $cl{"cline"});
devi@0 497 $cl{"euid"}=0 if defined $commands{"sudo"};
devi@0 498 my @comms = sort { $commands{$a} cmp $commands{$b} } keys %commands;
devi@0 499 $cl{"last_command"} = $comms[$#comms] || "";
devi@0 500
devi@0 501 if (
devi@0 502 $Config{"suppress_editors"} =~ /^y/i
devi@0 503 && grep ($_ eq $cl{"last_command"}, @{$Config{"editors"}}) ||
devi@0 504 $Config{"suppress_pagers"} =~ /^y/i
devi@0 505 && grep ($_ eq $cl{"last_command"}, @{$Config{"pagers"}}) ||
devi@0 506 $Config{"suppress_terminal"}=~ /^y/i
devi@0 507 && grep ($_ eq $cl{"last_command"}, @{$Config{"terminal"}})
devi@0 508 ) {
devi@0 509 $cl{"suppress_output"} = "1";
devi@0 510 }
devi@0 511 else {
devi@0 512 $cl{"suppress_output"} = "0";
devi@0 513
devi@0 514 }
devi@0 515 $skip_info = 0;
devi@0 516
devi@0 517
devi@0 518 print " ",$cl{"last_command"};
devi@0 519
devi@0 520 # Processing previous command line
devi@0 521 if ($first_pass) {
devi@0 522 $first_pass = 0;
devi@0 523 next;
devi@0 524 }
devi@0 525
devi@0 526 # Error code
devi@0 527 $last_cl{"err"}=$err;
devi@0 528 $last_cl{"err"}=130 if $err eq "^C";
devi@0 529
devi@0 530 if (grep ($_ eq $last_cl{"last_command"}, @{$Config{"editors"}})) {
devi@0 531 bind_diff(\%last_cl);
devi@0 532 }
devi@0 533
devi@0 534 # Output
devi@0 535 if (!$last_cl{"suppress_output"} || $last_cl{"err"}) {
devi@0 536 for (my $i=0; $i<$Config{"terminal_height"}; $i++) {
devi@0 537 my $line= $vt->row_plaintext($i);
devi@0 538 next if !defined ($line) || $line =~ /^\s*$/;
devi@0 539 $line =~ s/\s*$//;
devi@0 540 $last_cl{"output"} .= $line."\n";
devi@0 541 }
devi@0 542 }
devi@0 543 else {
devi@0 544 $last_cl{"output"}= "";
devi@0 545 }
devi@0 546
devi@0 547 $vt->reset();
devi@0 548
devi@0 549
devi@0 550 # Classifying the command line
devi@0 551
devi@0 552
devi@0 553 # Save
devi@0 554 if (!$Config{"lab"} || $cl{"lab"} eq $Config{"lab"}) {
devi@0 555 # Changing encoding
devi@0 556 for (keys %last_cl) {
devi@0 557 $last_cl{$_} = $converter->convert($last_cl{$_})
devi@0 558 if ($Config{"encoding"} &&
devi@0 559 $Config{"encoding"} !~ /^utf-8$/i);
devi@0 560 }
devi@0 561 push @Command_Lines, \%last_cl;
devi@0 562 }
devi@0 563 next;
devi@0 564 }
devi@0 565 $last_output_length+=length($_);
devi@0 566 #if (!$cl{"suppress_output"} || $last_output_length < 5000) {
devi@18 567 if ($last_output_length < 50000) {
devi@0 568 #print "(",length($_),")" if (length($_) > 2000) ;
devi@0 569 $vt->process("$_"."\n")
devi@0 570 }
devi@0 571 else
devi@0 572 {
devi@0 573 if (!$skip_info) {
devi@0 574 print "($cl{last_command})";
devi@0 575 $skip_info = 1;
devi@0 576 }
devi@0 577 }
devi@0 578 }
devi@0 579 close(FILE);
devi@0 580
devi@0 581 }
devi@0 582 if ($Config{"verbose"} =~ /y/) {
devi@0 583 print "...finished." ;
devi@0 584 print "Lines loaded: $commandlines_processed\n";
devi@0 585 print "Command lines: $commandlines_loaded\n";
devi@0 586 }
devi@0 587 }
devi@0 588
devi@0 589 sub search_by
devi@0 590 {
devi@0 591 my $sm = shift;
devi@0 592 my $topic = shift;
devi@0 593 $topic =~ s/ /+/;
devi@0 594
devi@0 595 return "<a href='". $Search_Machines{$sm}->{"query"}."$topic'><img width='16' height='16' src='".
devi@0 596 $Search_Machines{$sm}->{"icon"}."' border='0'/></a>";
devi@0 597 }
devi@0 598
devi@0 599 sub make_comment
devi@0 600 {
devi@0 601 my $commands = $_[0];
devi@0 602 my $files = $_[1];
devi@0 603 chomp $commands;
devi@0 604 chomp $files;
devi@0 605 return if (!$commands && !$files);
devi@0 606
devi@0 607 my $comment="";
devi@0 608
devi@0 609 # Commands
devi@0 610 for my $command (split /\s+/,$commands) {
devi@0 611 $command =~ s/'//g;
devi@0 612 my $description="";
devi@0 613 eval { $description=`mywi-client '$command'`; } ;
devi@0 614 $description = join ("<br>\n", grep(/\([18]\)/, split(/\n/, $description)));
devi@0 615 $description =~ s/.*?-//;
devi@0 616 next if $description =~ /^\s*$/;
devi@0 617
devi@0 618 my $query=$command." ".$Config{"keywords"};
devi@0 619 $query =~ s/\ /+/g;
devi@0 620 my $search= search_by("opennet",$query).
devi@0 621 search_by("local",$command).
devi@0 622 search_by("google",$query);
devi@0 623
devi@0 624 $comment .= "<tr><td class='note_title'>$command</td>".
devi@0 625 "<td class='note_search'>$search</td>".
devi@0 626 "</tr><tr><td width='100%' colspan='2' class='note_text'>".
devi@0 627 "$description</td></tr><tr/>";
devi@0 628 }
devi@0 629
devi@0 630 # Files
devi@0 631 for my $file (split /\s+/,$files) {
devi@0 632 $file =~ s@.*/@@;
devi@0 633 $file =~ s/'//g;
devi@0 634 next if $file =~ /^\s*$/;
devi@0 635 next if $file =~ /^-/;
devi@0 636
devi@0 637 my $description=`mywi '$file'`;
devi@0 638 $description = join ("<br>\n", grep(/\(5\)/, split(/\n/, $description)));
devi@0 639 next if $description =~ /^\s*$/;
devi@0 640
devi@0 641 my $query=$file." ".$Config{"files_keywords"};
devi@0 642 $query =~ s/\ /+/g;
devi@0 643 my $search= search_by("opennet",$query).
devi@0 644 search_by("local",$file).
devi@0 645 search_by("google",$query);
devi@0 646
devi@0 647 $comment .= "<tr><td class='note_title'>$file</td>".
devi@0 648 "<td class='note_search'>$search</td>".
devi@0 649 "</tr><tr><td width='100%' colspan='2' class='note_text'>".
devi@0 650 "$description</td></tr><tr/>";
devi@0 651 }
devi@0 652
devi@0 653
devi@0 654 return $comment;
devi@0 655 }
devi@0 656
devi@0 657 sub printq
devi@0 658 {
devi@0 659 my $TO = shift;
devi@0 660 my $text = join "", @_;
devi@0 661 $text =~ s/&/&amp;/g;
devi@0 662 $text =~ s/</&lt;/g;
devi@0 663 $text =~ s/>/&gt;/g;
devi@0 664 print $TO $text;
devi@0 665 }
devi@0 666
devi@0 667
devi@0 668 sub sort_command_lines
devi@0 669 {
devi@0 670 print "Sorting command lines...\n" if $Config{"verbose"} =~ /y/;
devi@0 671
devi@0 672 # Sort Command_Lines
devi@0 673 # Write Command_Lines to Command_Lines_Index
devi@0 674
devi@0 675 my @index;
devi@0 676 for (my $i=0;$i<=$#Command_Lines;$i++) {
devi@0 677 $index[$i]=$i;
devi@0 678 }
devi@0 679
devi@0 680 @Command_Lines_Index = sort {
devi@0 681 $Command_Lines[$index[$a]]->{"day"} cmp $Command_Lines[$index[$b]]->{"day"} ||
devi@0 682 $Command_Lines[$index[$a]]->{"hour"} <=> $Command_Lines[$index[$b]]->{"hour"} ||
devi@0 683 $Command_Lines[$index[$a]]->{"min"} <=> $Command_Lines[$index[$b]]->{"min"} ||
devi@0 684 $Command_Lines[$index[$a]]->{"sec"} <=> $Command_Lines[$index[$b]]->{"sec"}
devi@0 685 } @index;
devi@0 686
devi@0 687 print "...finished\n" if $Config{"verbose"} =~ /y/;
devi@0 688
devi@0 689 }
devi@0 690
devi@0 691 sub process_command_lines
devi@0 692 {
devi@0 693 my $lab_scripts_path = $_[0];
devi@0 694
devi@0 695 for my $i (@Command_Lines_Index) {
devi@0 696
devi@0 697 my $cl = \$Command_Lines[$i];
devi@0 698 @{${$cl}->{"new_commands"}} =();
devi@0 699 @{${$cl}->{"new_files"}} =();
devi@0 700 $$cl->{"class"} = "";
devi@0 701
devi@0 702 if ($$cl->{"err"}) {
devi@0 703 $$cl->{"class"}="wrong";
devi@0 704 $$cl->{"class"}="interrupted"
devi@0 705 if ($$cl->{"err"} eq 130);
devi@0 706 }
devi@0 707 if (!$$cl->{"euid"}) {
devi@0 708 $$cl->{"class"}.="_root";
devi@0 709 }
devi@0 710
devi@0 711 #tab# my @tab_words=split /\s+/, $$cl->{"output"};
devi@0 712 #tab# my $last_word= $$cl->{"cline"} =~ /(\S*)$/;
devi@0 713 #tab# $last_word =~ s@.*/@@;
devi@0 714 #tab# my $this_is_tab=1;
devi@0 715 #tab#
devi@0 716 #tab# if ($last_word && @tab_words >2) {
devi@0 717 #tab# for my $tab_words (@tab_words) {
devi@0 718 #tab# if ($tab_words !~ /^$last_word/) {
devi@0 719 #tab# $this_is_tab=0;
devi@0 720 #tab# last;
devi@0 721 #tab# }
devi@0 722 #tab# }
devi@0 723 #tab# }
devi@0 724 #tab# $$cl->{"class"}="tab" if $this_is_tab;
devi@0 725
devi@0 726
devi@0 727 if ( !$$cl->{"err"}) {
devi@0 728 # Command does not contain mistakes
devi@0 729
devi@0 730 my %commands = extract_from_cline("commands", ${$cl}->{"cline"});
devi@0 731 my %files = extract_from_cline("files", ${$cl}->{"cline"});
devi@0 732
devi@0 733 # Searching for new commands only
devi@0 734 for my $command (keys %commands) {
devi@0 735 if (!defined $Commands_Stat{$command}) {
devi@0 736 push @{$$cl->{new_commands}}, $command;
devi@0 737 }
devi@0 738 $Commands_Stat{$command}++;
devi@0 739 }
devi@0 740
devi@0 741 for my $file (keys %files) {
devi@0 742 if (!defined $Files_Stat{$file}) {
devi@0 743 push @{$$cl->{new_files}}, $file;
devi@0 744 }
devi@0 745 $Files_Stat{$file}++;
devi@0 746 }
devi@0 747 }
devi@0 748 }
devi@0 749
devi@0 750 }
devi@0 751
devi@6 752
devi@6 753 =cut
devi@6 754 Вывести результат обработки журнала.
devi@6 755 =cut
devi@6 756
devi@6 757
devi@0 758 sub print_command_lines
devi@0 759 {
devi@0 760 my $output_filename=$_[0];
devi@0 761 my $format = $Config{"output_format"};
devi@6 762
devi@6 763 my $course_name = $Config{"course-name"};
devi@6 764 my $course_code = $Config{"course-code"};
devi@6 765 my $course_date = $Config{"course-date"};
devi@6 766 my $course_center = $Config{"course-center"};
devi@6 767 my $course_trainer = $Config{"course-trainer"};
devi@6 768 my $course_student = $Config{"course-student"};
devi@0 769
devi@0 770 open(OUT, ">", $output_filename)
devi@0 771 or die "Can't open $output_filename for writing\n";
devi@0 772
devi@0 773
devi@0 774
devi@0 775 if ($format eq "html") {
devi@0 776 # vvvv HTML Header
devi@0 777 print OUT <<HEADER;
devi@0 778 <html>
devi@0 779 <head>
devi@0 780 <meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
devi@0 781 <link rel='stylesheet' href='labmaker.css' type='text/css'/>
devi@0 782 </head>
devi@0 783 <body>
devi@0 784 <script>
devi@0 785 function getElementsByClassName(Class_Name)
devi@0 786 {
devi@0 787 var Result=new Array();
devi@0 788 var All_Elements=document.all || document.getElementsByTagName('*');
devi@0 789 for (i=0; i<All_Elements.length; i++)
devi@0 790 if (All_Elements[i].className==Class_Name)
devi@0 791 Result.push(All_Elements[i]);
devi@0 792 return Result;
devi@0 793 }
devi@0 794 function ShowHide (name)
devi@0 795 {
devi@0 796 elements=getElementsByClassName(name);
devi@0 797 for(i=0; i<elements.length; i++)
devi@0 798 if (elements[i].style.display == "none")
devi@0 799 elements[i].style.display = "";
devi@0 800 else
devi@0 801 elements[i].style.display = "none";
devi@0 802 //if (elements[i].style.visibility == "hidden")
devi@0 803 // elements[i].style.visibility = "visible";
devi@0 804 //else
devi@0 805 // elements[i].style.visibility = "hidden";
devi@0 806 }
devi@0 807 function filter_by_output(text)
devi@0 808 {
devi@0 809
devi@0 810 var jjj=0;
devi@0 811
devi@0 812 elements=getElementsByClassName('command');
devi@0 813 for(i=0; i<elements.length; i++) {
devi@0 814 subelems = elements[i].getElementsByTagName('pre');
devi@0 815 for(j=0; j<subelems.length; j++) {
devi@0 816 if (subelems[j].className = 'output') {
devi@0 817 var str = new String(subelems[j].nodeValue);
devi@0 818 if (jjj != 1) {
devi@0 819 alert(str);
devi@0 820 jjj=1;
devi@0 821 }
devi@0 822 if (str.indexOf(text) >0)
devi@0 823 subelems[j].style.display = "none";
devi@0 824 else
devi@0 825 subelems[j].style.display = "";
devi@0 826
devi@0 827 }
devi@0 828
devi@0 829 }
devi@0 830 }
devi@0 831
devi@0 832 }
devi@0 833 </script>
devi@6 834 <h2>Журнал лабораторных работ</h2>
devi@6 835
devi@6 836 <p>
devi@6 837 Выполнил $course_student<br/>
devi@6 838 Проверил $course_trainer <br/>
devi@6 839 Курс $course_name ($course_code),
devi@6 840 $course_date<br/>
devi@6 841 Учебный центр $course_center <br/>
devi@6 842 </p>
devi@6 843
devi@6 844 <ul>
devi@6 845 <li><a href='#log'>Журнал</a></li>
devi@6 846 <li><a href='#stat'>Статистика</a></li>
devi@6 847 <li><a href='#help'>Справка</a></li>
devi@6 848 <li><a href='#about'>О программе</a></li>
devi@6 849 </ul>
devi@6 850
devi@12 851 <h3 id="log">Журнал</h3>
devi@0 852 HEADER
devi@0 853 print OUT "<table class='visibility_form'><tr><td><form>\n";
devi@0 854 for my $element (keys %Elements_Visibility)
devi@0 855 {
devi@0 856 my @e = split /\s+/, $element;
devi@0 857 my $showhide = join "", map { "ShowHide('$_');" } @e ;
devi@0 858 print OUT "<input type='checkbox' name='$e[0]' onclick=\"$showhide\" checked>",
devi@0 859 $Elements_Visibility{$element},
devi@0 860 "</input><br>\n";
devi@0 861 }
devi@0 862 #print OUT "<input type='text' size='10' name=\"by_command\"/>".
devi@0 863 #"<input type='button' value='фильтр по командам' onclick=\"filter_by_command()\"/> <br>\n";
devi@0 864 #print OUT "<input type='text' size='10' name=\"by_output\"/>".
devi@0 865 #"<input type='button' value='фильтр по результату' ".
devi@0 866 #"onclick=\"filter_by_output(this.form.by_output.value)\"/> <br>\n";
devi@0 867
devi@0 868 print OUT "</form></td></tr></table>\n";
devi@0 869 print OUT "<table width='100%'>\n";
devi@0 870 # ^^^^ HTML Header
devi@0 871 }
devi@0 872 else {
devi@0 873 # XML Header
devi@0 874 print OUT "<script>\n"
devi@0 875 }
devi@0 876
devi@0 877 my $cl;
devi@0 878 my $last_tty="";
devi@13 879 my $last_day="";
devi@0 880 my $in_range=0;
devi@0 881 for my $i (@Command_Lines_Index) {
devi@0 882
devi@13 883
devi@0 884 $cl = $Command_Lines[$i];
devi@0 885
devi@0 886 if ($Config{"from"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"from"}/) {
devi@0 887 $in_range=1;
devi@0 888 next;
devi@0 889 }
devi@0 890 if ($Config{"to"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"to"}/) {
devi@0 891 $in_range=0;
devi@0 892 next;
devi@0 893 }
devi@0 894 next if ($Config{"from"} && $Config{"to"} && !$in_range)
devi@0 895 ||
devi@0 896 ($Config{"skip_empty"} =~ /^y/i && $cl->{"cline"} =~ /^\s*$/ )
devi@0 897 ||
devi@0 898 ($Config{"skip_wrong"} =~ /^y/i && $cl->{"err"} != 0)
devi@0 899 ||
devi@0 900 ($Config{"skip_interrupted"} =~ /^y/i && $cl->{"err"} == 130);
devi@0 901
devi@0 902 my @new_commands=@{$cl->{"new_commands"}};
devi@0 903 my @new_files=@{$cl->{"new_files"}};
devi@0 904
devi@0 905 my $cl_class="cline";
devi@0 906 my $out_class="output";
devi@0 907 if ($cl->{"class"}) {
devi@0 908 $cl_class = $cl->{"class"}."_".$cl_class;
devi@0 909 $out_class = $cl->{"class"}."_".$out_class;
devi@0 910 }
devi@0 911
devi@0 912 my $output="";
devi@0 913 if ($Config{"head_lines"} || $Config{"tail_lines"}) {
devi@0 914 # Partialy output
devi@0 915 my @lines = split '\n', $cl->{"output"};
devi@0 916 # head
devi@0 917 my $mark=1;
devi@0 918 for (my $i=0; $i<= $#lines && $i < $Config{"head_lines"}; $i++) {
devi@0 919 $output .= $lines[$i]."\n";
devi@0 920 }
devi@0 921 # tail
devi@0 922 my $start=$#lines-$Config{"tail_lines"}+1;
devi@0 923 if ($start < 0) {
devi@0 924 $start=0;
devi@0 925 $mark=0;
devi@0 926 }
devi@0 927 if ($start < $Config{"head_lines"}) {
devi@0 928 $start=$Config{"head_lines"};
devi@0 929 $mark=0;
devi@0 930 }
devi@0 931 $output .= $Config{"skip_text"}."\n" if $mark;
devi@0 932 for (my $i=$start; $i<= $#lines; $i++) {
devi@0 933 $output .= $lines[$i]."\n";
devi@0 934 }
devi@0 935 }
devi@0 936 else {
devi@0 937 # Full output
devi@0 938 $output .= $cl->{"output"};
devi@0 939 }
devi@0 940 $output .= "^C\n" if ($cl->{"err"} eq "130");
devi@0 941
devi@0 942
devi@0 943 # Printing out
devi@0 944
devi@0 945 # <command>
devi@0 946 print OUT $format eq "html"
devi@0 947 ? "<tr class='command'>\n"
devi@0 948 : "\n<action time='$cl->{hour}:$cl->{min}:$cl->{sec}' tty='$cl->{tty}'>\n";
devi@0 949
devi@0 950
devi@0 951 if ($format eq "html") {
devi@13 952
devi@13 953 # DAY CHANGE
devi@13 954 if ( $last_day ne $cl->{"day"}) {
devi@13 955 print OUT "<td colspan='6'><p></p><h3>День ",$cl->{"day"},"</h4></td></tr><tr>";
devi@13 956 $last_day=$cl->{"day"};
devi@13 957 }
devi@13 958
devi@0 959 # CONSOLE CHANGE
devi@0 960 if ( $last_tty ne $cl->{"tty"}) {
devi@0 961 print OUT "<td colspan='6'><table><tr><td class='ttychange' width='140' align='center'>",$cl->{"tty"},"</td><td/></tr></table></td></tr><tr>";
devi@0 962 $last_tty=$cl->{"tty"};
devi@0 963 }
devi@0 964
devi@0 965 # TIME
devi@0 966 if ($Config{"show_time"} =~ /^y/i) {
devi@0 967 print OUT "<td valign='top' class='time' width='$Config{time_width}'><pre>",
devi@0 968 $cl->{"hour"}, ":", $cl->{"min"}, ":", $cl->{"sec"},
devi@0 969 "</td>";
devi@0 970 } else {
devi@0 971 print OUT "<td width='0'/>"
devi@0 972 }
devi@0 973 }
devi@0 974
devi@0 975 # COMMAND
devi@0 976
devi@0 977
devi@0 978 if ($format eq "html") {
devi@0 979 print OUT "<td class='script'>\n";
devi@0 980 print OUT "<pre class='$cl_class'>\n";
devi@0 981 my $cline = $cl->{"cline"};
devi@0 982 $cline =~ s/\n//;
devi@0 983 printq(\*OUT,$cl->{"prompt"},$cl->{"cline"});
devi@0 984 # printq(\*OUT,"(sudo ".$cl->{"last_command"}.")\n") if !$cl->{"euid"};
devi@0 985 print OUT "</pre>\n";
devi@0 986 }
devi@0 987 else {
devi@0 988 print OUT "<line class='$cl_class'>\n";
devi@0 989 print OUT "<prompt>";
devi@0 990 printq(\*OUT,$cl->{"prompt"});
devi@0 991 print OUT "</prompt>";
devi@0 992 print OUT "<command>";
devi@0 993 printq(\*OUT,$cl->{"cline"});
devi@0 994 print OUT "</command>";
devi@0 995 print OUT "\n</line>\n";
devi@0 996 }
devi@0 997
devi@0 998 my $last_command = $cl->{"last_command"};
devi@0 999 if (!(
devi@0 1000 $Config{"suppress_editors"} =~ /^y/i && grep ($_ eq $last_command, @{$Config{"editors"}}) ||
devi@0 1001 $Config{"suppress_pagers"} =~ /^y/i && grep ($_ eq $last_command, @{$Config{"pagers"}}) ||
devi@0 1002 $Config{"suppress_terminal"}=~ /^y/i && grep ($_ eq $last_command, @{$Config{"terminal"}})
devi@0 1003 )) {
devi@0 1004
devi@0 1005 if ($format eq "html") {
devi@0 1006 print OUT "<pre class='$out_class'>";
devi@0 1007 printq(\*OUT,$output);
devi@0 1008 print OUT "</pre>\n";
devi@0 1009 }
devi@0 1010 else {
devi@0 1011 print OUT "<output class='$out_class'>\n";
devi@0 1012 printq(\*OUT,$output);
devi@0 1013 print OUT "</output>\n";
devi@0 1014 }
devi@0 1015 }
devi@0 1016
devi@0 1017 # DIFF
devi@0 1018 if ( $Config{"show_diffs"} =~ /^y/i && $cl->{"diff"}) {
devi@0 1019 if ($format eq "html") {
devi@0 1020 #print Dumper(%{$cl->{"diff"}});
devi@0 1021 print OUT "<table><tr><td width='5'/><td class='diff'><pre>";
devi@0 1022 printq(\*OUT,${$Diffs[$cl->{"diff"}]}{"text"});
devi@0 1023 print OUT "</pre></td></tr></table>";
devi@0 1024 }
devi@0 1025 else {
devi@0 1026 print OUT "<diff>\n";
devi@0 1027 printq(\*OUT,${$Diffs[$cl->{"diff"}]}{"text"});
devi@0 1028 print OUT "</diff>\n";
devi@0 1029 }
devi@0 1030 }
devi@0 1031
devi@0 1032 # COMMENT
devi@0 1033 if ( $Config{"show_comments"} =~ /^y/i) {
devi@0 1034 my $comment = make_comment(join(" ",@new_commands), join (" ",@new_files));
devi@0 1035 if ($comment) {
devi@0 1036 if ($format eq "html") {
devi@0 1037 print OUT "<table width='$Config{comment_width}'>".
devi@0 1038 "<tr><td width='5'/><td>";
devi@0 1039 print OUT "<table class='note' width='100%'>";
devi@0 1040 print OUT $comment;
devi@0 1041 print OUT "</table>\n";
devi@0 1042 print OUT "</td></tr></table>";
devi@0 1043 }
devi@0 1044 # else {
devi@0 1045 # print OUT "<comment>";
devi@0 1046 # printq(\*OUT,$comment);
devi@0 1047 # print OUT "</comment>";
devi@0 1048 # }
devi@0 1049 }
devi@0 1050 }
devi@0 1051
devi@0 1052 if ($format eq "html") {
devi@0 1053 print OUT "</td>\n";
devi@0 1054 print OUT "</tr>\n";
devi@0 1055 }
devi@0 1056 else {
devi@0 1057 print OUT "</action>\n";
devi@0 1058 }
devi@0 1059
devi@0 1060 }
devi@0 1061 if ($format eq "html") {
devi@0 1062 print OUT "</table>\n";
devi@6 1063
devi@6 1064 print OUT "<hr/>";
devi@6 1065 print OUT "<h3 id='stat'>Статистика</h4>";
devi@6 1066 print OUT "Статистическая информация о журнале<br/>";
devi@6 1067 print OUT "<hr/>";
devi@6 1068 print OUT "<h3 id='help'>Справка</h4>";
devi@6 1069 print OUT "$Html_Help<br/>";
devi@6 1070 print OUT "<hr/>";
devi@6 1071 print OUT "<h3 a='about'>О программе</h4>";
devi@6 1072 print OUT "$Html_About";
devi@0 1073 print OUT "</body>\n";
devi@0 1074 print OUT "</html>\n";
devi@0 1075 }
devi@0 1076 else {
devi@0 1077 print OUT "</script>\n";
devi@0 1078 }
devi@0 1079 close(OUT);
devi@0 1080 }
devi@0 1081
devi@0 1082 sub read_config_file
devi@0 1083 {
devi@0 1084 my $config = $_[0];
devi@0 1085 my $filename = $_[1];
devi@0 1086 open(CONFIG, "$filename")
devi@0 1087 or return;
devi@0 1088 while (<CONFIG>) {
devi@0 1089 s/#.*//;
devi@0 1090 next if /^\s*$/;
devi@0 1091 my ($var, $val) = split /\s*=\s*/, $_, 2;
devi@0 1092 $var =~ s/\s*//;
devi@0 1093 $config->{$var} = $val;
devi@0 1094 }
devi@0 1095 close(CONFIG);
devi@0 1096 }
devi@0 1097
devi@18 1098
devi@18 1099 sub print_command_lines2
devi@18 1100 {
devi@18 1101 my $output_filename=$_[0];
devi@18 1102 open(OUT, ">", $output_filename)
devi@18 1103 or die "Can't open $output_filename for writing\n";
devi@18 1104
devi@18 1105
devi@18 1106 print OUT <<OUT;
devi@18 1107 <log>
devi@18 1108 OUT
devi@18 1109
devi@18 1110 my $cl;
devi@18 1111 for my $i (@Command_Lines_Index) {
devi@18 1112
devi@18 1113
devi@18 1114 $cl = $Command_Lines[$i];
devi@18 1115
devi@18 1116
devi@18 1117 # Printing out
devi@18 1118 print OUT <<OUT;
devi@18 1119 <command>
devi@18 1120 <day>$cl->{day}</day>
devi@18 1121 <hour>$cl->{hour}</hour>
devi@18 1122 <min>$cl->{min}</min>
devi@18 1123 <sec>$cl->{sec}</sec>
devi@18 1124 <tty>$cl->{tty}</tty>
devi@18 1125 <uid>$cl->{uid}</uid>
devi@18 1126 <euid>$cl->{euid}</euid>
devi@18 1127 <prompt>$cl->{prompt}</prompt>
devi@18 1128 <cline>$cl->{cline}</cline>
devi@18 1129 <status>$cl->{err}</cline>
devi@18 1130 <output>
devi@18 1131 $cl->{output}</output>
devi@18 1132 </command>
devi@18 1133 OUT
devi@18 1134 }
devi@18 1135
devi@18 1136 for my $diff (@Diffs) {
devi@18 1137
devi@18 1138 print OUT <<OUT;
devi@18 1139 <diff>
devi@18 1140 <path>$diff->{path}</path>
devi@18 1141 <uid>$diff->{uid}</uid>
devi@18 1142 <day>$diff->{day}</day>
devi@18 1143 <hour>$diff->{hour}</hour>
devi@18 1144 <min>$diff->{min}</min>
devi@18 1145 <sec>$diff->{sec}</sec>
devi@18 1146 <text>
devi@18 1147 $diff->{text}</text>
devi@18 1148 </diff>
devi@18 1149 OUT
devi@18 1150 }
devi@18 1151
devi@18 1152 print OUT <<OUT;
devi@18 1153 </log>
devi@18 1154 OUT
devi@18 1155 }
devi@18 1156
devi@18 1157
devi@0 1158 $| = 1;
devi@0 1159
devi@0 1160 my %file_config;
devi@0 1161 my %argv_config;
devi@6 1162 init_variables;
devi@0 1163 read_config_file(\%file_config, $Config_File);
devi@0 1164 GetOptions(\%argv_config, map "$_=s", keys %Config);
devi@0 1165 %Config = (%Config, %file_config, %argv_config);
devi@0 1166
devi@0 1167 my $i=0;
devi@0 1168
devi@0 1169 for my $lab_log (split (/\s+/, $Config{"diffs"} || $Config{"input"}))
devi@0 1170 {
devi@0 1171 load_diff_files($lab_log);
devi@0 1172 }
devi@0 1173
devi@0 1174 for my $lab_log (split /\s+/, $Config{"input"})
devi@0 1175 {
devi@0 1176 my $tofile=$Config{"output"};
devi@0 1177 $tofile =~ s/$Config{"output_mask"}/$i/;
devi@0 1178 #load_diff_files($lab_log);
devi@0 1179 load_command_lines($lab_log, $Config{"input_mask"});
devi@0 1180 sort_command_lines;
devi@0 1181 process_command_lines($lab_log);
devi@0 1182 print_command_lines($tofile);
devi@0 1183 $i++;
devi@0 1184 }
devi@0 1185
devi@6 1186