#! /usr/bin/perl # $Id$ # Copyright (C) 2001-2005 Mandriva # Yves Duret # some code is Copyright: (C) 1999, Michael T. Babcock # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # TODO: consider switching from TreeView to gtkhtml use strict; use lib qw(/usr/lib/libDrakX); use standalone; #- warning, standalone must be loaded very first, for 'explanations' use common; use interactive; use ugtk2 qw(:create :dialogs :helpers :wrappers); $ugtk2::wm_icon = "/usr/share/mcc/themes/default/logdrake-mdk.png"; my $in = 'interactive'->vnew('su'); my ($isExplain, $Explain, $isFile, $File, $isWord, $Word); #- parse arguments list. foreach (@ARGV) { /^--explain=(.*)$/ and do { $isExplain = ($Explain) = $1; $isFile = 1; $File = "/var/log/explanations"; next }; /^--file=(.*)$/ and do { $isFile = ($File) = $1; next }; /^--word=(.*)$/ and do { $isWord = ($Word) = $1; next }; /^--alert$/ and do { alert_config(); quit() }; } my $isTail = $isFile; $| = 1 if $isTail; my $h = chomp_(`hostname -s`); $ugtk2::wm_icon = "logdrake"; my $explain_title = N("Mandriva Linux Tools Logs"); my $my_win = ugtk2->new($isExplain ? $explain_title : N("Logdrake")); unless ($::isEmbedded) { $my_win->{window}->set_border_width(5); #$my_win->{window}->set_default_size(540,460); } $my_win->{window}->signal_connect(delete_event => \&quit); my $cal = gtkset_sensitive(Gtk2::Calendar->new, 0); my $mday = (localtime(time()))[3]; $cal->select_day($mday); my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); my $cal_mode = 0; my $cal_butt = gtksignal_connect(Gtk2::CheckButton->new(N("Show only for the selected day")), clicked => sub { $cal_mode = !$cal_mode; gtkset_sensitive($cal,$cal_mode) }); ### menus definition # the menus are not shown # but they provides shiny shortcut like C-q my @menu_items = ( { path => N("/_File"), item_type => '' }, { path => N("/File/_New"), accelerator => N("N") }, { path => N("/File/_Open"), accelerator => N("O") }, { path => N("/File/_Save"), accelerator => N("S"), callback => \&save }, { path => N("/File/Save _As") }, { path => N("/File/-"), item_type => '' }, { path => N("/File/_Quit"), accelerator => N("Q"), callback => \&quit }, { path => N("/_Options"), item_type => '' }, { path => N("/Options/Test") }, { path => N("/_Help"), item_type => '' }, { path => N("/Help/_About...") } ); my $_menubar = $::isEmbedded ? create_factory_menu($my_win->{rwindow}, @menu_items) : undef; ######### menus end ########## font and colors # Define global terms: # Define good notables: my @word_good = ("starting\n", "Freeing", "Detected", "starting.", "accepted.\n", "authenticated.\n", "Ready", "active", "reloading", "saved;", "restarting", "ONLINE\n"); my @word_warn = ("dangling", "closed.\n", "Assuming", "root", "root\n", "exiting\n", "missing", "Ignored", "adminalert:", "deleting", "OFFLINE\n"); my @word_bad = "bad"; my @word_note = ("LOGIN", "DHCP_OFFER", "optimized", "reset:", "unloaded", "disconnected", "connect", "Successful", "registered\n"); #my @line_good = ("up", "DHCP_ACK", "Cleaned", "Initializing", "Starting", "success", "successfully", "alive", "found", "ONLINE\n"); #my @line_warn = ("warning:", "WARNING:", "invalid", "obsolete", "bad", "Password", "detected", "timeout", "timeout:", "attackalert:", "wrong", "Lame", "FAILED", "failing", "unknown", "obsolete", "stopped.\n", "terminating.", "disabled\n", "disabled", "Lost"); #my @line_bad = ("DENY", "lost", "shutting", "dead", "DHCP_NAK", "failure;", "Unable", "inactive", "terminating", "refused", "rejected", "down", "OFFLINE\n", "error\n", "ERROR\n", "ERROR:", "error", "ERROR", "error:", "failed:"); # Now define what we want to use when: my $col_good = 'green4'; my $col_warn = 'yellow4'; my $col_bad = 'red'; my $col_note = 'purple'; my $col = 'darkcyan'; ######### font and colors end my %files = ( "auth" => { file => "/var/log/auth.log", desc => N("_:this is the auth.log log file\nAuthentication") }, "user" => { file => "/var/log/user.log", desc => N("_:this is the user.log log file\nUser") }, "messages" => { file => "/var/log/messages", desc => N("_:this is the /var/log/messages log file\nMessages") }, "syslog" => { file => "/var/log/syslog", desc => N("_:this is the /var/log/syslog log file\nSyslog") }, "explanations" => { file => "/var/log/explanations", desc => $explain_title } ); my $yy = gtkset_sensitive(gtksignal_connect(Gtk2::Button->new(N("search")) , clicked => \&search),0); my $log_text = gtktext_insert(Gtk2::TextView->new, [ [ '' ] ]); my $log_buf = $log_text->get_buffer; my $refcount_search; #### far from window my %toggle; gtkadd($my_win->{window}, gtkpack_(Gtk2::VBox->new(0,0), if_(!$isExplain && !$::isEmbedded, 0, N("A tool to monitor your logs")), if_(!$isFile, 0, gtkadd(Gtk2::Frame->new(N("Settings")), gtkpack__(Gtk2::VBox->new(0,2), gtkpack__(Gtk2::VBox->new(0,2), # N("Show lines"), gtkpack__(Gtk2::HBox->new(0,0), " " . N("Matching") . " ", my $e_yes = Gtk2::Entry->new, " " . N("but not matching") . " ", my $e_no = Gtk2::Entry->new ) ), gtkpack_(Gtk2::HBox->new(0,0), 1, gtkadd(gtkset_border_width(Gtk2::Frame->new(N("Choose file")),2), gtkpack(gtkset_border_width(Gtk2::VBox->new(0,0),0), map { $toggle{$_} = gtksignal_connect(Gtk2::CheckButton->new($files{$_}{desc}), clicked => sub { $refcount_search++; gtkset_sensitive($yy, $refcount_search); }) } sort keys %files, ) ), 0, gtkadd(gtkset_border_width(Gtk2::Frame->new(N("Calendar")),2), gtkpack__(gtkset_border_width(Gtk2::VBox->new(0,0),5), $cal_butt, $cal ) ) ), $yy, ) ) ), !$isExplain ? (1, gtkadd(Gtk2::Frame->new(N("Content of the file")), create_scrolled_window($log_text) )) : (1, create_scrolled_window($log_text)), if_(!$isExplain, 0, gtkadd(gtkset_border_width(gtkset_layout(Gtk2::HButtonBox->new, 'end'), 5), if_(!$isFile, gtksignal_connect(Gtk2::Button->new(N("Mail alert")), clicked => sub { eval { alert_config() }; my $err = $@; $::WizardWindow->destroy if defined $::WizardWindow; undef $::WizardWindow; if ($err && $err !~ /wizcancel/) { err_dialog(N("Error"), N("The alert wizard has failed unexpectedly:") . "\n\n" . $err); } })), gtksignal_connect(Gtk2::Button->new(N("Save")), clicked => \&save), gtksignal_connect(Gtk2::Button->new($::isEmbedded ? N("Cancel") : N("Quit")), clicked => \&quit) ) ) ) ); $isFile && !$::isEmbedded and gtkset_size_request($log_text, 400, 500); $my_win->{window}->show_all; search() if $isFile; $my_win->main; sub quit() { ugtk2->exit(0) } #------------------------------------------------------------- # search functions #------------------------------------------------------------- sub search() { return if !$log_text->window; $log_text->window->freeze_updates; $log_buf->set_text(''); if ($isFile) { parse_file($File, $File); } else { foreach (keys %files) { parse_file($files{$_}{file}, $files{$_}{desc}) if $toggle{$_}->get_active; } } $log_text->window->thaw_updates; $log_text->show; gtkflush(); } my $timer; my @logs; my $F; sub parse_file { my ($file, $descr) = @_; $file =~ s/\.gz$//; my ($pbar, $win_pb); unless ($::isEmbedded && $isExplain) { local $::main_window = $my_win->{real_window}; gtkadd($win_pb = gtkset_modal(Gtk2::Window->new('toplevel'), 1), gtkpack(Gtk2::VBox->new(2,0), Gtk2::Label->new(" " . N("please wait, parsing file: %s", $descr) . " "), $pbar = Gtk2::ProgressBar->new ) ); $win_pb->set_transient_for($my_win->{real_window}); $win_pb->set_position('center'); $win_pb->realize; $win_pb->show_all; gtkflush(); } my $ey = $e_yes->get_chars(0, -1); my $en = $e_no->get_chars(0, -1); $ey =~ s/ OR /|/; $ey =~ s/^\*$//; $en =~ s/^\*$/.*/; $ey = $ey . $Word if $isWord; if ($cal_mode) { my (undef, $month, $day) = $cal->get_date; $ey = $months[$month] . "\\s{1,2}$day\\s.*$ey.*\n"; } my @all = catMaybeCompressed($file); if ($isExplain) { my (@t, $t); while (@all) { $t = pop @all; next if $t =~ /logdrake/; last if $t !~ /$Explain/; push @t, $t; } @all = reverse @t; } my $taille = @all; my $i = 0; my $test; if ($en && !$ey) { $test = sub { $_[0] !~ /$en/ }; } elsif ($ey && !$en) { $test = sub { $_[0] =~ /$ey/ }; } else { $test = sub { $_[0] =~ /$ey/ && $_[0] !~ /$en/ }; } foreach (@all) { $i++; if ($pbar && $i % 10) { $pbar->set_fraction($i/$taille); $win_pb->window->process_updates(1); # no gtkflush() because we do not want to refresh the TextView } logcolorize($_) if $test->($_); } $win_pb->destroy if !$::isEmbedded || !$isExplain; if ($isTail) { close $F if $F; open $F, $file or die "E: $!"; local $_; while (<$F>) {} #to prevent to output the file twice.. # $log_text->set_point($log_text->get_length()); $timer ||= Glib::Timeout->add(1000, sub { logcolorize($_) while <$F>; seek $F, 0, 1; }); } insert_text_n_scroll(); } ########################################################################################## sub logcolorize { local $_ = shift; #my ($data) = @_; # we get date & time if it is date & time (dmesg) s/(\D{3} .. (\d\d:\d\d:\d\d ))//; my $timestamp = $isExplain ? $2 : $1; my @rec = split; log_output($timestamp, 'Bold', 'darkcyan'); # date & time if any... # BUG: $col hasn't yet be reseted $isExplain or log_output("$rec[0] ", 'Bold', $rec[0] eq $h ? 'blue' : $col); # hostname if ($rec[1] eq "last") { log_output(" last message repeated ", undef, 'green'); log_output($rec[4], 'Bold', 'green'); log_output(" times\n", undef, 'green'); return; } # Extract PID if present if ($rec[1] =~ /\[(\d+)\]:/) { my $pid = $1; $rec[1] =~ s/\[$1\]://; log_output($rec[1] . "[", undef, 'green'); log_output($pid, 'Bold', 'black'); log_output("]: ", undef, 'green'); } else { log_output($rec[1] . " ", undef, 'green'); } foreach my $therest (2 .. $#rec) { $col = 'darkcyan'; # Check for keywords to highlight foreach (@word_good) { $col = $col_good if $_ eq $rec[$therest] } foreach (@word_warn) { $col = $col_warn if $_ eq $rec[$therest] } foreach (@word_bad) { $col = $col_bad if $_ eq $rec[$therest] } foreach (@word_note) { $col = $col_note if $_ eq $rec[$therest] } # Watch for words that indicate entire lines should be highlighted #foreach (@line_good) { $col = $col_good if $_ eq $rec[$therest] } #foreach (@line_warn) { $col = $col_warn if $_ eq $rec[$therest] } #foreach (@line_bad) { $col = $col_bad if $_ eq $rec[$therest] } log_output("$rec[$therest] ", undef, $col); } log_output("\n", undef, 'black'); insert_text_n_scroll() if $isExplain; } # log_output (Gtk2::TextView, [ [ ... ] ]) sub log_output { my ($text, $font, $col) = @_; my $tag = join('', $font, $col); push @logs, [ $text, $tag ]; $log_buf->{tags}{$tag} ||= { foreground => $col }; # if_($font, font => $font), } sub insert_text_n_scroll() { ugtk2::gtktext_insert($log_text, \@logs, append => 1); $log_text->scroll_to_iter($log_buf->get_end_iter, 0, 1, 0.5, 0.5); undef @logs; } #------------------------------------------------------------- # mail/sms alert #------------------------------------------------------------- sub alert_config() { local $::isEmbedded = 0; undef $::WizardTable; undef $::WizardWindow; my $conffile = "/etc/sysconfig/mail_alert"; my %options = getVarsFromSh($conffile); $options{LOAD} ||= 3; $options{MAIL} ||= "root"; $options{SMTP} ||= "localhost"; my $service = { httpd => N("Apache World Wide Web Server"), bind => N("Domain Name Resolver"), ftp => N("Ftp Server"), postfix => N("Postfix Mail Server"), samba => N("Samba Server"), sshd => N("SSH Server"), webmin => N("Webmin Service"), xinetd => N("Xinetd Service") }; my @installed_d = grep { -e "/etc/init.d/$_" } sort keys %$service; my %services_to_check = map { $_ => 1 } split(':', $options{SERVICES}); $::isWizard = 1; use wizards; my $w = wizards->new; my $mode; my $cron_file = "/etc/cron.hourly/logdrake_service"; my %modes = ( configure => N("Configure the mail alert system"), disable => N("Stop the mail alert system"), ); my $wiz = { defaultimage => "logdrake.png", name => N("Mail alert"), pages => { welcome => { name => N("Mail alert configuration") . "\n\n" . N("Welcome to the mail configuration utility.\n\nHere, you'll be able to set up the alert system.\n"), no_back => 1, data => [ { val => \$mode, label => N("What do you want to do?"), list => [ keys %modes ], format => sub { $modes{$_[0]} }, }, ], post => sub { $mode eq 'configure' ? 'services' : 'stop' }, }, services => { name => N("Services settings") . "\n\n" . N("You will receive an alert if one of the selected services is no longer running"), data => [ map { { label => $_, val => \$services_to_check{$_}, type => "bool", text => $service->{$_} } } @installed_d ], next => "load", }, load => { #PO- Here "load" is a noun; that is load refers to the system/CPU) load name => N("Load setting") . "\n\n" . N("You will receive an alert if the load is higher than this value"), data => [ { label => N("_: load here is a noun, the load of the system\nLoad"), val => \$options{LOAD}, type => 'range', min => 1, max => 50 } ], next => "email", }, email => { name => N("Alert configuration") . "\n\n" . N("Please enter your email address below ") . "\n" . N("and enter the name (or the IP) of the SMTP server you wish to use"), data => [ { label => "Email address", val => \$options{MAIL} }, { label => "Email server", val => \$options{SMTP} }, ], complete => sub { if ($options{MAIL} !~ /[\w.-]*\@[\w.-]/ && !member($options{MAIL}, map { $_->[0] } list_passwd())) { err_dialog(N("Error"), N("\"%s\" neither is a valid email nor is an existing local user!", $options{MAIL})); return 1; } if (member($options{MAIL}, map { $_->[0] } list_passwd()) && $options{SMP} !~ /localhost/) { err_dialog(N("Error"), N("\"%s\" is a local user, but you did not select a local smtp, so you must use a complete email address!", $options{MAIL})); return 1; } }, next => "end", }, end => { name => N("Congratulations") . "\n\n" . N("The wizard successfully configured the mail alert."), end => 1, no_back => 1, }, stop => { pre => sub { eval { rm_rf($cron_file) } }, name => N("Congratulations") . "\n\n" . N("The wizard successfully disabled the mail alert."), end => 1, no_back => 1, }, }, }; $w->process($wiz, $in); return if $mode eq 'disable'; $options{SERVICES} = join ':', grep { $services_to_check{$_} } sort keys %services_to_check; use Data::Dumper; output_with_perm $cron_file, 0755, q(#!/usr/bin/perl # generated by logdrake use MDK::Common; my $r; my %options = getVarsFromSh("/etc/sysconfig/mail_alert"); #- check services my ) . Data::Dumper->Dump([ $service ], [qw(*services)]) . q( foreach (split(':', $options{SERVICES})) { next unless $services{$_}; $r .= "Service $_ ($services{$_} is not running)\\n" unless -e "/var/lock/subsys/$_"; } #- load my ($load) = split ' ', first(cat_("/proc/loadavg")); $r .= "Load is huge: $load\n" if $load > $options{LOAD}; #- report it if ($r) { use Mail::Mailer; my $mailer = Mail::Mailer->new('smtp', Server => $options{SMTP}); $mailer->open({ From => 'root@localhost', To => $options{MAIL}, Subject => "DrakLog Mail Alert", }) or die "Can not open: $!\n"; print $mailer $r; $mailer->close; } # EOF); setVarsInSh($conffile, \%options); if (defined $::WizardWindow) { $::WizardWindow->destroy; undef $::WizardWindow; } } #------------------------------------------------------------- # menu callback functions #------------------------------------------------------------- sub save() { $::isWizard = 0; my $y = $in->ask_filename({ title => N("Save as.."), directory => "/root", save => 1 }) or return; my $buf = $log_text->get_buffer; my ($start, $end) = $buf->get_bounds; output($y, $buf->get_text($start, $end, 0)); } a id='n428' href='#n428'>428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
package help;
use common;

1;

# IMPORTANT: Do not edit this File - It is automatically generated 
#            from the manuals !!! 
#            Write a mail to <documentation@mandrakesoft.com> if
#            you want it changed.
sub acceptLicense() {
    N("Before continuing, you should carefully read the terms of the license. It
covers the entire Mandrakelinux distribution. If you agree with all the
terms it contains, check the \"%s\" box. If not, clicking on the \"%s\"
button will reboot your computer.", N("Accept"), N("Quit"));
}
sub addUser() {
    N("GNU/Linux is a multi-user system which means each user can have his or her
own preferences, own files and so on. But unlike \"root\", who is the
system administrator, the users you add at this point will not be authorized
to change anything except their own files and their own configurations,
protecting the system from unintentional or malicious changes which could
impact on the system as a whole. You'll have to create at least one regular
user for yourself -- this is the account which you should use for routine,
day-to-day usage. Although it's very easy to log in as \"root\" to do
anything and everything, it may also be very dangerous! A very simple
mistake could mean that your system will not work any more. If you make a
serious mistake as a regular user, the worst that can happen is that you'll
lose some information, but you will not affect the entire system.

The first field asks you for a real name. Of course, this is not mandatory
-- you can actually enter whatever you like. DrakX will use the first word
you type in this field and copy it to the \"%s\" one, which is the name
this user will enter to log onto the system. If you like, you may override
the default and change the user name. The next step is to enter a password.
From a security point of view, a non-privileged (regular) user password is
not as crucial as the \"root\" password, but that's no reason to neglect it
by making it blank or too simple: after all, your files could be the ones
at risk.

Once you click on \"%s\", you can add other users. Add a user for each one
of your friends, your father, your sister, etc. Click \"%s\" when you're
finished adding users.

Clicking the \"%s\" button allows you to change the default \"shell\" for
that user (bash by default).

When you're finished adding users, you'll be asked to choose a user who
will be automatically logged into the system when the computer boots up. If
you're interested in that feature (and do not care much about local
security), choose the desired user and window manager, then click on
\"%s\". If you're not interested in this feature, uncheck the \"%s\" box.", N("User name"), N("Accept user"), N("Next"), N("Advanced"), N("Next"), N("Do you want to use this feature?"));
}
sub ask_mntpoint_s() {
    N("Listed here are the existing Linux partitions detected on your hard drive.
You can keep the choices made by the wizard, since they are good for most
common installations. If you make any changes, you must at least define a
root partition (\"/\"). Do not choose too small a partition or you will not
be able to install enough software. If you want to store your data on a
separate partition, you will also need to create a \"/home\" partition
(only possible if you have more than one Linux partition available).

Each partition is listed as follows: \"Name\", \"Capacity\".

\"Name\" is structured: \"hard drive type\", \"hard drive number\",
\"partition number\" (for example, \"hda1\").

\"Hard drive type\" is \"hd\" if your hard drive is an IDE hard drive and
\"sd\" if it is a SCSI hard drive.

\"Hard drive number\" is always a letter after \"hd\" or \"sd\". For IDE
hard drives:

 * \"a\" means \"master hard drive on the primary IDE controller\";

 * \"b\" means \"slave hard drive on the primary IDE controller\";

 * \"c\" means \"master hard drive on the secondary IDE controller\";

 * \"d\" means \"slave hard drive on the secondary IDE controller\".

With SCSI hard drives, an \"a\" means \"lowest SCSI ID\", a \"b\" means
\"second lowest SCSI ID\", etc.");
}
sub chooseCd() {
    N("The Mandrakelinux installation is distributed on several CD-ROMs. If a
selected package is located on another CD-ROM, DrakX will eject the current
CD and ask you to insert the required one. If you do not have the requested
CD at hand, just click on \"%s\", the corresponding packages will not be
installed.", N("Cancel"));
}
sub choosePackages() {
    N("It's now time to specify which programs you wish to install on your system.
There are thousands of packages available for Mandrakelinux, and to make it
simpler to manage, they have been placed into groups of similar
applications.

Mandrakelinux sorts package groups in four categories. You can mix and
match applications from the various categories, so a ``Workstation''
installation can still have applications from the ``Server'' category
installed.

 * \"%s\": if you plan to use your machine as a workstation, select one or
more of the groups in the workstation category.

 * \"%s\": if you plan on using your machine for programming, select the
appropriate groups from that category. The special \"LSB\" group will
configure your system so that it complies as much as possible with the
Linux Standard Base specifications.

   Selecting the \"LSB\" group will also install the \"2.4\" kernel series,
instead of the default \"2.6\" one. This is to ensure 100%%-LSB compliance
of the system. However, if you do not select the \"LSB\" group you will
still have a system which is nearly 100%% LSB-compliant.

 * \"%s\": if your machine is intended to be a server, select which of the
more common services you wish to install on your machine.

 * \"%s\": this is where you will choose your preferred graphical
environment. At least one must be selected if you want to have a graphical
interface available.

Moving the mouse cursor over a group name will display a short explanatory
text about that group.

You can check the \"%s\" box, which is useful if you're familiar with the
packages being offered or if you want to have total control over what will
be installed.

If you start the installation in \"%s\" mode, you can deselect all groups
and prevent the installation of any new packages. This is useful for
repairing or updating an existing system.

If you deselect all groups when performing a regular installation (as
opposed to an upgrade), a dialog will pop up suggesting different options
for a minimal installation:

 * \"%s\": install the minimum number of packages possible to have a
working graphical desktop.

 * \"%s\": installs the base system plus basic utilities and their
documentation. This installation is suitable for setting up a server.

 * \"%s\": will install the absolute minimum number of packages necessary
to get a working Linux system. With this installation you will only have a
command-line interface. The total size of this installation is about 65
megabytes.", N("Workstation"), N("Development"), N("Server"), N("Graphical Environment"), N("Individual package selection"), N("Upgrade"), N("With X"), N("With basic documentation"), N("Truly minimal install"));
}
sub choosePackagesTree() {
    N("If you choose to install packages individually, the installer will present
a tree containing all packages classified by groups and subgroups. While
browsing the tree, you can select entire groups, subgroups, or individual
packages.

Whenever you select a package on the tree, a description will appear on the
right to let you know the purpose of that package.

!! If a server package has been selected, either because you specifically
chose the individual package or because it was part of a group of packages,
you'll be asked to confirm that you really want those servers to be
installed. By default Mandrakelinux will automatically start any installed
services at boot time. Even if they are safe and have no known issues at
the time the distribution was shipped, it is entirely possible that
security holes were discovered after this version of Mandrakelinux was
finalized. If you do not know what a particular service is supposed to do or
why it's being installed, then click \"%s\". Clicking \"%s\" will install
the listed services and they will be started automatically at boot time. !!

The \"%s\" option is used to disable the warning dialog which appears
whenever the installer automatically selects a package to resolve a
dependency issue. Some packages depend on others and the installation of
one particular package may require the installation of another package. The
installer can determine which packages are required to satisfy a dependency
to successfully complete the installation.

The tiny floppy disk icon at the bottom of the list allows you to load a
package list created during a previous installation. This is useful if you
have a number of machines that you wish to configure identically. Clicking
on this icon will ask you to insert the floppy disk created at the end of
another installation. See the second tip of the last step on how to create
such a floppy.", N("No"), N("Yes"), N("Automatic dependencies"));
}
sub configurePrinter() {
    N("\"%s\": clicking on the \"%s\" button will open the printer configuration
wizard. Consult the corresponding chapter of the ``Starter Guide'' for more
information on how to set up a new printer. The interface presented in our
manual is similar to the one used during installation.", N("Printer"), N("Configure"));
}
sub configureServices() {
    N("This dialog is used to select which services you wish to start at boot
time.

DrakX will list all services available on the current installation. Review
each one of them carefully and uncheck those which are not needed at boot
time.

A short explanatory text will be displayed about a service when it is
selected. However, if you're not sure whether a service is useful or not,
it is safer to leave the default behavior.

!! At this stage, be very careful if you intend to use your machine as a
server: you probably do not want to start any services which you do not need.
Please remember that some services can be dangerous if they're enabled on a
server. In general, select only those services you really need. !!");
}
sub configureTimezoneGMT() {
    N("GNU/Linux manages time in GMT (Greenwich Mean Time) and translates it to
local time according to the time zone you selected. If the clock on your
motherboard is set to local time, you may deactivate this by unselecting
\"%s\", which will let GNU/Linux know that the system clock and the
hardware clock are in the same time zone. This is useful when the machine
also hosts another operating system.

The \"%s\" option will automatically regulate the system clock by
connecting to a remote time server on the Internet. For this feature to
work, you must have a working Internet connection. We recommend that you
choose a time server located near you. This option actually installs a time
server which can be used by other machines on your local network as well.", N("Hardware clock set to GMT"), N("Automatic time synchronization"));
}
sub configureX_card_list() {
    N("Graphic Card

   The installer will normally automatically detect and configure the
graphic card installed on your machine. If this is not correct, you can
choose from this list the card you actually have installed.

   In the situation where different servers are available for your card,
with or without 3D acceleration, you're asked to choose the server which
best suits your needs.");
}
sub configureX_chooser() {
    N("X (for X Window System) is the heart of the GNU/Linux graphical interface
on which all the graphical environments (KDE, GNOME, AfterStep,
WindowMaker, etc.) bundled with Mandrakelinux rely upon.

You'll see a list of different parameters to change to get an optimal
graphical display.

Graphic Card

   The installer will normally automatically detect and configure the
graphic card installed on your machine. If this is not correct, you can
choose from this list the card you actually have installed.

   In the situation where different servers are available for your card,
with or without 3D acceleration, you're asked to choose the server which
best suits your needs.



Monitor

   Normally the installer will automatically detect and configure the
monitor connected to your machine. If it is not correct, you can choose
from this list the monitor which is connected to your computer.



Resolution

   Here you can choose the resolutions and color depths available for your
graphics hardware. Choose the one which best suits your needs (you will be
able to make changes after the installation). A sample of the chosen
configuration is shown in the monitor picture.



Test

   Depending on your hardware, this entry might not appear.

   The system will try to open a graphical screen at the desired
resolution. If you see the test message during the test and answer \"%s\",
then DrakX will proceed to the next step. If you do not see it, then it
means that some part of the auto-detected configuration was incorrect and
the test will automatically end after 12 seconds and return you to the
menu. Change settings until you get a correct graphical display.



Options

   This steps allows you to choose whether you want your machine to
automatically switch to a graphical interface at boot. Obviously, you may
want to check \"%s\" if your machine is to act as a server, or if you were
not successful in getting the display configured.", N("Yes"), N("No"));
}
sub configureX_monitor() {
    N("Monitor

   Normally the installer will automatically detect and configure the
monitor connected to your machine. If it is not correct, you can choose
from this list the monitor which is connected to your computer.");
}
sub configureX_resolution() {
    N("Resolution

   Here you can choose the resolutions and color depths available for your
graphics hardware. Choose the one which best suits your needs (you will be
able to make changes after the installation). A sample of the chosen
configuration is shown in the monitor picture.");
}
sub configureX_xfree_and_glx() {
    N("In the situation where different servers are available for your card, with
or without 3D acceleration, you're asked to choose the server which best
suits your needs.");
}
sub configureXxdm() {
    N("Options

   This steps allows you to choose whether you want your machine to
automatically switch to a graphical interface at boot. Obviously, you may
want to check \"%s\" if your machine is to act as a server, or if you were
not successful in getting the display configured.", N("No"));
}
sub doPartitionDisks() {
    N("You now need to decide where you want to install the Mandrakelinux
operating system on your hard drive. If your hard drive is empty or if an
existing operating system is using all the available space you will have to
partition the drive. Basically, partitioning a hard drive means to
logically divide it to create the space needed to install your new
Mandrakelinux system.

Because the process of partitioning a hard drive is usually irreversible
and can lead to data losses, partitioning can be intimidating and stressful
for the inexperienced user. Fortunately, DrakX includes a wizard which
simplifies this process. Before continuing with this step, read through the
rest of this section and above all, take your time.

Depending on the configuration of your hard drive, several options are
available: