а еще не менее интересно что делают иксы, чтобы прибить кириллицу.
Код: Выделить всё
#!/usr/bin/perl
# cyr -- Setup Cyrillic on Linux console
# Copyright (C) 1999,2000,2001,2002,2003,2006 Anton Kirilov Zinoviev
# 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 of the License, 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.
# If you have not received a copy of the GNU General Public License
# along with this program, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Contact the author by e-mail: anton@lml.bas.bg, zinoviev@fmi.uni-sofia.bg
use strict;
my $INSTALLDIR=$0;
$INSTALLDIR =~ s+/[^/]*$++g;
$INSTALLDIR .= "/..";
# $INSTALLDIR="/usr";
# $INSTALLDIR="/usr/local";
my $STDF="/usr/share/consolefonts";
my $ALTSTDF="${INSTALLDIR}/share/consolefonts";
my $FONTDIR="${INSTALLDIR}/share/console-cyrillic";
my $CONSOLETRANSDIR="${INSTALLDIR}/share/console-cyrillic";
my $KEYMAPDIR="${INSTALLDIR}/share/console-cyrillic";
my $MYCONFFILE = "";
if (`whoami` ne "root") {
$MYCONFFILE = "$ENV{HOME}/.cyr_defaults";
} else {
$MYCONFFILE = "/etc/console-cyrillic";
}
my $CONFFILE = "";
if (-f "$ENV{HOME}/.cyr_defaults" && `whoami` ne "root") {
$CONFFILE = "$ENV{HOME}/.cyr_defaults";
} elsif (-f "/etc/console-cyrillic") {
$CONFFILE = "/etc/console-cyrillic";
}
my $t;
if ( -x "/usr/bin/consolechars" || -x "/bin/consolechars" ) {
$t="console-tools";
} elsif ( -x "/usr/bin/setfont" || -x "/bin/setfont" ) {
$t="kbd";
} else {
&err("cyr: In the system is not installed any of the known\ncyr: console packages. \n");
}
my $verbose='>/dev/null 2>&1';
my $commands='no';
my ($STYLE, $SIZE, $ENCODING, $LAYOUT, $OPTIONS, $FONTFILE, $VTTYS) =
("", "", "", "", "", "", "");
if ($CONFFILE) {
open CONFFILE, $CONFFILE;
for (<CONFFILE>) {
if (/^ *\#/) {next;}
if (/^ *$/) {next;}
my @words = split;# For compatability with the old (pre 0.7-2) format:
if ($words[0] =~ /^-/) {
my $args = "@words @ARGV";
@ARGV = split ' ', $args;
} elsif ($words[0] eq "options") {
shift @words;
$OPTIONS = "@words";
} elsif ($words[0] eq "ttys") {
shift @words;
$VTTYS = "@words";
} else {
if ($words[2]) {
&err("cyr: Syntax error in the configuration file:\n".
"cyr: ". $_ ."\n");
}
if ($words[0] eq "style") { $STYLE = $words[1];}
elsif ($words[0] eq "size") { $SIZE = $words[1];}
elsif ($words[0] eq "encoding") { $ENCODING = $words[1];}
elsif ($words[0] eq "layout") { $LAYOUT = $words[1];}
elsif ($words[0] eq "fontfile") { $FONTFILE = $words[1];}
else {
&err("cyr: Syntax error in the configuration file:\n".
"cyr: ". $_ ."\n");
}
}
}
close CONFFILE;
}
my ($km_old, $save, $layread, $fontfileread)=("","","no","no");
while ( $ARGV[0] ) {
my $op = &get_opt;
for ($op) {
if (/^-C$|^--copyright$/) {
&no_arg;
print STDOUT <<EOF;
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 bash interpreter; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
EOF
exit;
} elsif (/^-k$|^--keymap$/) {
$km_old = &get_arg;
} elsif (/^-m$|^--mode$/) {
my $arg = &get_arg;
if ($arg eq "80x25" || $arg eq "80x30") {
$SIZE = "16";
} elsif ($arg eq "80x28" || $arg eq "80x34") {
$SIZE = "14";
} elsif ($arg eq "80x43"||$arg eq "80x50"||$arg eq "80x60") {
$SIZE = "8";
} else {
&err("cyr: Unknown video mode $arg.\n");
}
} elsif (/^--font$/) {
$FONTFILE = &get_arg;
$fontfileread = "yes";
} elsif (/^-f$|^--size$/) {
$SIZE = &get_arg;
} elsif (/^-s$|^--style$/) {
$STYLE = &get_arg;
} elsif (/^-e$|^--encoding$/) {
$ENCODING = &get_arg;
} elsif (/^--ttys$/) {
$VTTYS = &get_arg;
} elsif (/^-h$|^--help$/) {
&no_arg;
my $LTTY=`tty`;
chomp $LTTY;
print STDOUT <<EOF;
cyr -- Setup Cyrillic on Linux console
Usage: cyr [OPTIONS]... [KEYBOARD [KBD_OPTIONS ... ]]
-C, --copyright display copying conditions and warranty information
-h, --help display this help and exit
--save saves given parameters as default for latter usage
-v, --verbose verbose mode
--commands output the commands cyr executes
-s, --style=FONTSTYLE
-f, --size=FONTSIZE Posible FONTSTYLEs and FONTSIZEs are:
styles b, c, lenta, antiq and sans with size 16;
styles a, alt, uni, iso and dos with sizes 8, 14 and 16;
style arab with sizes 8, 14, 16 and 19;
style cage with sizes 8, 10, 11, 12, 14, 15, 16, 18 and 19;
style thin with sizes 14 and 16;
style sarge with size 16;
style pln with size 8;
styles a-asia, b-asia and antiq-asia with size 16;
styles ter-CHARSET-FACE with sizes 14 and 16,
where CHARSET is uni, asia or slav and FACE is norm, bold or framebuf.
--font=FONTFILE Font file to use. Overwrites --style and --size.
-e, --encoding=ENCODING Possible ENCODINGs are:
utf-8 (unicode), cp1251 (ms-cyr, 1251), ibm866 (dos-cyr-ru, cp866, 866),
iso-8859-5 (cyrillic), koi8-r, koi8-u, mac-cyrillic (mac-cyr),
mik (dos-cyr-bg), pt154 (asian-cyr), rk1048.
--ttys=\'TTY1 TTY2 ... \' Setup Cyrillic in these consoles.
Current default: $LTTY.
Supported KEYBOARDs are bg_bds, bg_phon, by, kaz_alt, kaz_gost, mk, mn,
ru, ru_ms, sr, ua and ua_ms.
Supported KBD_OPTIONS are toggle, ctrl_shift_toggle, caps_toggle,
ctrl_alt_toggle, alt_shift_toggle, right_ctrl_toggle, menu_toggle, lwin_toggle,
rwin_toggle, switch, menu_switch, win_switch, lwin_switch and rwin_switch.
Examples: cyr mk alt_shift_toggle --style arab -f19 -e iso-8859-5 --save
cyr ru caps_toggle --style=sans --size 16 -e koi8-r --save
cyr bg_bds toggle -s antiq -f16 --encoding=cp1251 --save
These are for the first usage. Then it is enough just to type
cyr
EOF
exit;
} elsif (/^--save$/) {
&no_arg;
$save="yes";
} elsif (/^-v$|^--verbose$/) {
&no_arg;
$verbose='';
} elsif (/^--commands$/) {
&no_arg;
$commands='yes';
} elsif (/^arg$/) {
my $arg = &get_arg;
if ( $LAYOUT eq "" || $layread eq "no") {
$LAYOUT = $arg;
$OPTIONS = "";
$layread = "yes";
} else {
if (-f "${CONSOLETRANSDIR}/option-$arg.kmap") {
$OPTIONS = "$OPTIONS $arg";
} else {
&err("cyr: Unknown keyboard option: ${arg}.\n");
}
}
} else {
&err("cyr: Unknown option: $_\n");
}
}
}
if(! (`tty` =~ m!/dev/tty[0-9]+|/dev/vc/[0-9]+|/dev/console!)) {
&err("cyr: This command may be executed only in Linux console.\n");
}
if ($fontfileread eq "no" && ($STYLE ne "" || $SIZE ne "")) {
$FONTFILE = "";
}
if ($LAYOUT eq "") {
$LAYOUT = $km_old;
}
if ($LAYOUT eq "") {
&err("cyr: What keyboard to use?\n");
}
if ($FONTFILE eq "") {
if ($STYLE eq "") {
&err("cyr: What font style to use?\n");
}
if ($SIZE eq "") {
&err("cyr: What font size to use?\n");
}
}
if ($ENCODING eq "") {
&err("cyr: What encoding to use?\n");
}
$ENCODING =~ tr/A-Z/a-z/;
for ($ENCODING) {
if(/^cp1251$|^ms-cyr$|^1251$/) {$ENCODING = "cp1251";}
elsif (/^utf-8$|^unicode$/) {$ENCODING = "unicode";}
elsif (/^ibm866$|^dos-cyr-ru$|^cp866$|^866$/) {$ENCODING = "ibm866";}
elsif (/^iso-8859-5$|^cyrillic$/) {$ENCODING = "iso-8859-5";}
elsif (/^mac-cyr$|^mac-cyrillic$/) {$ENCODING = "mac-cyrillic";}
elsif (/^mik$|^dos-cyr-bg$/) {$ENCODING = "mik";}
elsif (/^pt154$|^asian-cyr$/) {$ENCODING = "pt154";}
elsif (/^rk1048$/) {$ENCODING = "rk1048";}
elsif (! /^koi8-[ru]$/) {
&err("cyr: Unknown encoding `$_'.\n");
}
}
$LAYOUT =~ tr/A-Z/a-z/;
for ($LAYOUT) {
if(/^bds$/) {$LAYOUT = "bg_bds";}
elsif (/^phon$/) {$LAYOUT = "bg_phon";}
elsif (! /^sr$|^ua$|^ua_ms$|^ru$|^ru_ms$|^by$|^mk$|^mn$|^bg_bds$|^bg_phon$|^kaz_alt$|^kaz_gost$/) {
&err("cyr: Unknown keyboard: $_\n");
}
}
$STYLE =~ tr/A-Z/a-z/;
for ($STYLE) {
if(/^1$/) {$STYLE = "a";}
elsif(/^2$|^3$/) {$STYLE = "alt";}
elsif(/^4$/) {$STYLE = "arab";}
}
if($VTTYS eq "") {
$VTTYS = `tty`;
}
for my $console (glob $VTTYS) {
if (-w $console) {
open CONSOLE, ">$console";
print CONSOLE "\x{1b}(K";
if ($ENCODING eq "unicode") {
print CONSOLE "\x{1b}%G";
} else {
print CONSOLE "\x{1b}%@";
}
close CONSOLE;
}
}
if ($FONTFILE eq "") {
&stylesize($STYLE, $SIZE);
} else {
&loadfont($FONTFILE);
}
if($t eq "kbd") {
&kbd_encoding($ENCODING);
} elsif ($t eq "console-tools") {
&console_tools_encoding($ENCODING);
} else {&err("??????????????????\n")}
if($t eq "console-tools") {
&execute( "consolechars -v -k ${CONSOLETRANSDIR}/cyrillic-graph.fallback.gz".
" $verbose");
}
if ($ENCODING eq "unicode") {
&execute ("kbd_mode -u");
} else {
&execute ("kbd_mode -a");
}
&execute ("loadkeys ${KEYMAPDIR}/$LAYOUT-$ENCODING.kmap $verbose");
if ("$OPTIONS" ne "") {
&execute ("loadkeys ${KEYMAPDIR}/option-clear.kmap $verbose");
for my $op (split ' ', $OPTIONS) {
&execute ("loadkeys ${KEYMAPDIR}/option-${op}.kmap $verbose");
}
}
if ($save eq "yes") {
if (`whoami` eq "root") {
print STDERR "Warning: root may not use the option --save.\n";
} else {
if ($verbose eq "") {
print STDERR "Saving default options for the next time.\n";
}
open CONFFILE, ">$MYCONFFILE";
if ($FONTFILE eq "") {
print CONFFILE "style $STYLE\n";
print CONFFILE "size $SIZE\n";
} else {
print CONFFILE "fontfile $FONTFILE\n";
}
print CONFFILE "encoding $ENCODING\n";
print CONFFILE "layout $LAYOUT\n";
if ($OPTIONS) {print CONFFILE "options $OPTIONS\n";}
close CONFFILE;
}
}
sub execute {
printf STDERR "%s\n", $_[0] if ($commands eq 'yes');
system ($_[0]);
}
sub loadfont {
if ($t eq "kbd") {
for my $tty (glob $VTTYS) {
&execute ("setfont -v $_[0] -C ${tty} ${verbose}");
}
} else {
for my $tty (glob $VTTYS) {
&execute ("consolechars -v -f $_[0] --tty=${tty} ${verbose}");
}
}
}
sub stylesize {
my ($style, $size) = @_;
my $font;
for ($style){
if (/^a$/) {$font = "${FONTDIR}/Cyr_a8x${size}.psf";}
elsif (/^pln$/) {$font = "${FONTDIR}/UniCyrX-pln-8x${size}.psf";}
elsif (/^ibm$/) {$font = "${FONTDIR}/UniCyrX-ibm-8x${size}.psf";}
elsif (/^b$/) {$font = "${FONTDIR}/alt-b-8x${size}.psf";}
elsif (/^c$/) {$font = "${FONTDIR}/alt-c-8x${size}.psf";}
elsif (/^uni$/) {$font = "${FONTDIR}/UniCyr_8x${size}.psf";}
elsif (/^alt$/) {$font = "${FONTDIR}/alt_8x${size}.psf";}
elsif (/^dos$/) {$font = "${FONTDIR}/866_8x${size}.psf";}
elsif (/^antiq$/) {$font = "${FONTDIR}/alt-antiq-8x${size}.psf";}
elsif (/^lenta$/) {$font = "${FONTDIR}/UniCyr-lenta-8x${size}.psf";}
elsif (/^sans$/) {$font = "${FONTDIR}/UniCyr-sans-8x${size}.psf";}
elsif (/^cage$/) {$font = "${FONTDIR}/CAG-8x${size}.psf";}
elsif (/^thin$/) {$font = "${FONTDIR}/thin-${size}.psf";}
elsif (/^sarge$/) {$font = "${FONTDIR}/sarge-${size}.psf";}
elsif (/^a-asia$/) {$font = "${FONTDIR}/pt154_a8x${size}.psf";}
elsif (/^b-asia$/) {$font = "${FONTDIR}/pt154_b8x${size}.psf";}
elsif (/^antiq-asia$/) {$font = "${FONTDIR}/pt154_antiq8x${size}.psf";}
elsif (/^ter-uni-norm$/) {
$font = "${ALTSTDF}/Uni3-Terminus${size}.psf.gz";
} elsif (/^ter-uni-bold$/) {
$font = "${ALTSTDF}/Uni3-TerminusBoldVGA${size}.psf.gz";
} elsif (/^ter-uni-framebuf$/) {
$font = "${ALTSTDF}/Uni3-TerminusBold${size}.psf.gz";
} elsif (/^ter-slav-norm$/) {
$font = "${ALTSTDF}/CyrSlav-Terminus${size}.psf.gz";
} elsif (/^ter-slav-bold$/) {
$font = "${ALTSTDF}/CyrSlav-TerminusBoldVGA${size}.psf.gz";
} elsif (/^ter-slav-framebuf$/) {
$font = "${ALTSTDF}/CyrSlav-TerminusBold${size}.psf.gz";
} elsif (/^ter-asia-norm$/) {
$font = "${ALTSTDF}/CyrAsia-Terminus${size}.psf.gz";
} elsif (/^ter-asia-bold$/) {
$font = "${ALTSTDF}/CyrAsia-TerminusBoldVGA${size}.psf.gz";
} elsif (/^ter-asia-framebuf$/) {
$font = "${ALTSTDF}/CyrAsia-TerminusBold${size}.psf.gz";
} elsif (/^arab$/) {
# if($t eq "kbd") { &err("cyr: The style ${style} is not possible on your system.\n"); }
if($size eq "8") {$size = "08";}
$font = "${STDF}/LatArCyrHeb-${size}.psf.gz";}
elsif (/^iso$/) {
# if($t eq "kbd") { &err("cyr: The style ${style} is not possible on your system.\n"); }
if($size eq "8") {$size = "08";}
$font = "${STDF}/iso05.f${size}.psf.gz";}
else { &err("cyr: Font style `$_' is not known.\n"); }
}
if (-f $font) {
&loadfont($font);
} else {
&err("cyr: Font size ${size} is not possible with style `${style}'.\n");
}
}
sub kbd_encoding {
for ($_[0]) {
if (/^cp1251$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/cp1251_to_uni.trans $verbose");
} elsif (/^ibm866$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/cp866_to_uni.trans $verbose");
} elsif (/^iso-8859-5$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/8859-5_to_uni.trans $verbose");
} elsif (/^koi8-r$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/koi8-r_to_uni.trans $verbose");
} elsif (/^koi8-u$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/koi8-u_to_uni.trans $verbose");
} elsif (/^mac-cyrillic$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/mac-cyrillic_to_uni.trans $verbose");
} elsif (/^mik$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/mik_to_uni.trans $verbose");
} elsif (/^pt154$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/pt154_to_uni.trans $verbose");
} elsif (/^rk1048$/) {
&execute ("setfont -m ${CONSOLETRANSDIR}/rk1048_to_uni.trans $verbose");
} elsif (/^unicode$/) {
} else {
&err("cyr: Unknown encoding `$_'.\n");
}
}
}
sub console_tools_encoding {
for ($_[0]) {
if (/^cp1251$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/cp1251.acm.gz $verbose");
} elsif (/^ibm866$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/cp866.acm.gz $verbose");
} elsif (/^iso-8859-5$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/iso8859-5.acm.gz $verbose");
} elsif (/^koi8-r$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/koi8-r.acm.gz $verbose");
} elsif (/^koi8-u$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/koi8-u.acm.gz $verbose");
} elsif (/^mac-cyrillic$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/MacCyrillic.acm.gz $verbose");
} elsif (/^mik$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/bulgarian-mic.acm.gz $verbose");
} elsif (/^pt154$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/pt154.acm.gz $verbose");
} elsif (/^rk1048$/) {
&execute ("consolechars -v --acm ${CONSOLETRANSDIR}/rk1048.acm.gz $verbose");
} elsif (/^unicode$/) {
} else {
&err("cyr: Unknown encoding `$_'.\n");
}
}
}
sub err {
printf STDERR $_[0];
printf STDERR "cyr: Try `cyr --help for more information.\n";
exit 2;
}
my $op;
sub get_opt {
for (my $arg=$ARGV[0]) {
if (/^-$/) {
$op = "arg";
} elsif (/^--[^=]*/ || /^-./) {
$op = $&;
} else {
$op = "arg";
}
}
return $op;
}
sub get_arg {
for ($ARGV[0]) {
shift @ARGV;
if (/^-$/) {
return "-";
} elsif (/^--[^=]*=(.*)/ || /^-[^-](..*)/) {
if ($1) { return $1; }
&err("cyr: Option ". $op ." requires an argument.\n");
} elsif (/^-/) {
my $arg = shift @ARGV;
if ($arg) {
return $arg;
} else {
&err("cyr: Option ". $op ." requires an argument.\n");
}
} else {
return $_;
}
}
}
sub no_arg {
for ($ARGV[0]) {
if (/^--.*=/) {
&err("cyr: Option `${op}' doesn't allow an argument.\n");
} elsif (/^-[^-](..*)/) {
$ARGV[0] = "-$1";
} else {
shift @ARGV;
}
}
}