diff options
author | Dexter Morgan <dmorgan@mageia.org> | 2011-06-02 20:51:35 +0000 |
---|---|---|
committer | Dexter Morgan <dmorgan@mageia.org> | 2011-06-02 20:51:35 +0000 |
commit | a9b2bdafaf625d10aef2f476aa4014fd36c846bc (patch) | |
tree | 2364afc0ee6739b59a25c44d68c9f003bcaf03d9 /tools | |
download | drakx-backup-do-not-use-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.tar drakx-backup-do-not-use-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.tar.gz drakx-backup-do-not-use-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.tar.bz2 drakx-backup-do-not-use-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.tar.xz drakx-backup-do-not-use-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.zip |
Branch for updates
Diffstat (limited to 'tools')
-rw-r--r-- | tools/.perl_checker | 10 | ||||
-rw-r--r-- | tools/Makefile | 27 | ||||
-rwxr-xr-x | tools/checkusedmodules | 22 | ||||
-rwxr-xr-x | tools/drakx-in-chroot | 228 | ||||
-rw-r--r-- | tools/extractchangelog | 2 | ||||
-rwxr-xr-x | tools/get-needed-drakx-modules | 19 | ||||
-rwxr-xr-x | tools/hd_grub.cgi | 102 | ||||
-rwxr-xr-x | tools/install-xml-file-list | 383 | ||||
-rw-r--r-- | tools/make_lang_png_transparent.c | 167 | ||||
-rwxr-xr-x | tools/mdkinst_stage2_tool | 66 | ||||
-rw-r--r-- | tools/ntp_servers.pl | 303 | ||||
-rw-r--r-- | tools/rpcinfo-flushed.c | 740 | ||||
-rw-r--r-- | tools/serial_probe/Makefile | 13 | ||||
-rw-r--r-- | tools/serial_probe/device.h | 104 | ||||
-rw-r--r-- | tools/serial_probe/kudzu.h | 26 | ||||
-rw-r--r-- | tools/serial_probe/serial.c | 1136 | ||||
-rw-r--r-- | tools/serial_probe/serial.h | 43 | ||||
-rw-r--r-- | tools/serial_probe/serial_probe.c | 114 | ||||
-rw-r--r-- | tools/shift_all.pl | 113 | ||||
-rw-r--r-- | tools/shift_img.c | 165 | ||||
-rwxr-xr-x | tools/simplify-drakx-modules | 5 | ||||
-rwxr-xr-x | tools/specific_arch | 9 | ||||
-rw-r--r-- | tools/xhost+.c | 11 |
23 files changed, 3808 insertions, 0 deletions
diff --git a/tools/.perl_checker b/tools/.perl_checker new file mode 100644 index 000000000..8dc1d2d7d --- /dev/null +++ b/tools/.perl_checker @@ -0,0 +1,10 @@ +AutoLoader +Carp::Heavy +constant +Cwd +Digest::base +Encode +File::Path +Gtk2::Gdk::Keysyms +IO::Handle +Pod::Usage
\ No newline at end of file diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 000000000..669b6f987 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,27 @@ +DIRS = serial_probe +CFLAGS = -Wall + +ARCH := $(shell arch | egrep "(x86_64|sparc64|s390x)") +ifneq ("x$(ARCH)", "x") +LIB_NAME = lib64 +else +LIB_NAME = lib +endif + +.PHONY: clean install $(DIRS) + +all: $(DIRS) xhost+ rpcinfo-flushed + +$(DIRS): + make -C $@ + +install: + install -d $(ROOTDEST)/misc + install mdkinst_stage2_tool drakx-in-chroot $(ROOTDEST)/misc + +xhost+: %: %.c + $(CC) $(CFLAGS) $< -L/usr/X11R6/$(LIB_NAME) -lX11 -o $@ + +clean: + for i in $(DIRS); do $(MAKE) -C $$i clean; done + rm -rf *~ xhost+ rpcinfo-flushed */*.o diff --git a/tools/checkusedmodules b/tools/checkusedmodules new file mode 100755 index 000000000..433ed54d9 --- /dev/null +++ b/tools/checkusedmodules @@ -0,0 +1,22 @@ +#!/bin/sh + +# This script compares the perl modules used by the .pm files in perl-install +# against the ones listed in share/list, to detect potential missing modules +# (and potential run-time problems during the stage 2) + +cd ../perl-install || exit 1; + +# list of used .pm files +find . -name '*.pm' -not -name b_dump_strings.pm -not -path ./interactive/http.pm | \ + xargs perl -lne '/^\s*(use|require)\s+([\w:]+)/ && print $2' | sort -u > /tmp/gi-used-pm + +# list of .pm files included in install +perl -lne 'm{/(?:PERL_VERSION|ARCH-linux|vendor_perl/\*)/([\w/]+)\.pm$} and $_=$1, s,/,::,g, print' share/list > /tmp/gi-found-pm0 +find . -name blib -prune -o -name '*.pm' | perl -ne 's,^\./,,; s/\.pm$// or next; s,/,::,g; print' >> /tmp/gi-found-pm0 + +# compute difference +sort -u /tmp/gi-found-pm0 > /tmp/gi-found-pm +diff -u /tmp/gi-{used,found}-pm | perl -lne 'BEGIN{print"Unpackaged modules:"} s/^-(?!-)/ / && print' + +# cleanup +rm -f /tmp/gi-used-pm /tmp/gi-found-pm{,0} diff --git a/tools/drakx-in-chroot b/tools/drakx-in-chroot new file mode 100755 index 000000000..a4064ed5b --- /dev/null +++ b/tools/drakx-in-chroot @@ -0,0 +1,228 @@ +#!/usr/bin/perl + +use MDK::Common; + +my $SLASH_LOCATION = '/tmp/drakx-in-chroot'; + +my $verbose = 0; +my $prefix_ROOTED = '/mnt'; +my $IMAGE_LOCATION_ROOTED = '/tmp/image'; +my $MEDIA_LOCATION_ROOTED = '/tmp/media'; +my $STAGE2_LOCATION_ROOTED = '/tmp/stage2'; +my $LOOP_MOUNT_POINT = "$SLASH_LOCATION/tmp/loop"; +my $LIVE_LOCATION_REL = 'install/stage2/live/'; +my $COMPRESSED_LOCATION_REL = 'install/stage2/'; +my $COMPRESSED_FILE_REL = $COMPRESSED_LOCATION_REL . 'mdkinst.sqfs'; +my $AUTO_INSTALL_ROOTED = '/tmp/auto_inst.cfg.pl'; +my $DEFCFG_ROOTED = '/tmp/defcfg.pl'; +my $RPMSRATE_ROOTED = '/tmp/rpmsrate'; +my $resolution = '800x600'; +my ($disk_iso_repository, $repository_uri); + +@ARGV >= 2 or die "usage: drakx-in-chroot <root of distrib> <dir to install to> [options]\n +\nOptions specific to drakx-in-chroot: + --flang XX use XX locale + --disk-iso path of a distro + --resolution=XXXxYYYY (eg: --resolution=1024x768)\n + --repository=<path> path of packages repository + --text text mode installer +"; + +(my $repository, my $dir, @ARGV) = @ARGV; +foreach (@ARGV) { + if (/--resolution=(.*)/) { + $resolution = $1; + } elsif (/--disk-iso=(.*)/) { + $disk_iso_repository = $1; + } elsif (/--repository=(.*)/) { + $repository_uri = $1; + } +} +my ($repository_without_arch, $repository_arch) = basename($repository) eq arch() ? (dirname($repository), '/' . arch()) : ($repository, ''); +my $STAGE2_LOCATION = $SLASH_LOCATION . $STAGE2_LOCATION_ROOTED; + +my $sudo; +if ($>) { + $sudo = "sudo"; + $ENV{PATH} = "/sbin:/usr/sbin:$ENV{PATH}"; +} + +undef $ENV{TMPDIR}; # prevent packdrake faillure on creating temporary files + +if (-d $SLASH_LOCATION) { + umount_all() == 0 or exit(1); + sys("$sudo rm -rf $SLASH_LOCATION/var/lib/rpm $SLASH_LOCATION/dev/mapper"); + rm_rf($SLASH_LOCATION); +} + +mkdir_p("$SLASH_LOCATION$_") foreach '/dev', '/dev/usb', '/etc', '/var', '/proc', '/sys', $STAGE2_LOCATION_ROOTED, $MEDIA_LOCATION_ROOTED, $prefix_ROOTED; + +sys("$sudo rm -rf $dir") if $ENV{CLEAN}; +-e $dir or sys("$sudo mkdir -p $dir"); + +copy_auto_install_files(); + +my $remote_repository = $repository =~ m!^(ftp|http)://! && $1; +if ($remote_repository) { + my $local_mdkinst = "$SLASH_LOCATION/tmp/mdkinst.sqfs"; + sys("curl --silent -o $local_mdkinst $repository/$COMPRESSED_FILE_REL"); + mount_mdkinst($local_mdkinst); +} elsif (-d "$repository/$LIVE_LOCATION_REL") { + sys("$sudo mount -o bind $repository/$LIVE_LOCATION_REL $STAGE2_LOCATION"); +} elsif (-e "$repository/$COMPRESSED_FILE_REL") { + mount_mdkinst("$repository/$COMPRESSED_FILE_REL"); +} + +sys("$sudo mount -o bind $dir $SLASH_LOCATION$prefix_ROOTED"); +$repository_uri ||= $repository_without_arch if !$remote_repository; +sys("$sudo mount -o bind $repository_uri $SLASH_LOCATION$MEDIA_LOCATION_ROOTED") if $repository_uri; + +sys("$sudo mount -t proc none $SLASH_LOCATION/proc"); +sys("$sudo mount -t sysfs none $SLASH_LOCATION/sys"); + +if ($disk_iso_repository) { + my $repository_arch = $repository_arch || 'i586'; + mkdir_p($LOOP_MOUNT_POINT); + sys("$sudo mount -o loop,ro $disk_iso_repository $LOOP_MOUNT_POINT"); + symlinkf('loop/' . $repository_arch, "$SLASH_LOCATION$IMAGE_LOCATION_ROOTED"); # FIXME: arch() +} + +symlinkf('media' . $repository_arch, "$SLASH_LOCATION$IMAGE_LOCATION_ROOTED"); +create_initial_symlinks(); +create_initial_devices(); + +apply_stage2_updates(); + +output("$SLASH_LOCATION/etc/hosts", "127.0.0.1 localhost\n") if ! -e "$SLASH_LOCATION/etc/hosts"; + +#- in the chroot, we have no way to know which device corresponds to the "/" partition. +#- so helping it by giving the device which provide major/minor information +mkdir_p("$dir/dev"); +eval { cp_af($_, "$dir$_") } foreach qw(/dev/root); + +#- if the DISPLAY is remote, we may need to resolve the name: +eval { cp_af($_, "$SLASH_LOCATION$_") } foreach qw(/etc/resolv.conf); + +{ + chomp(my $kernel_version = `uname -r`); + my $dir = "/modules/$kernel_version"; + mkdir_p("$SLASH_LOCATION$dir"); + output_p("$SLASH_LOCATION$dir" . $_, "\n") foreach "/lib/$dir/modules.dep", "/lib/$dir/modules.alias"; +} + +my $Xnest_pid; +my $Xnest_bin = find { whereis_binary($_) } 'Xephyr', 'Xnest'; +if (!-f ($SLASH_LOCATION . $AUTO_INSTALL_ROOTED) && $Xnest_bin && (join('', @ARGV) !~ /--text/)) { + my $DISPLAY = ':8'; + $Xnest_pid = fork(); + if (!$Xnest_pid) { + exec $Xnest_bin, $DISPLAY, '-ac', ($Xnest_bin eq 'Xephyr' ? '-screen' : '-geometry'), $resolution or die "Xnest failed\n"; + } + $ENV{DISPLAY} = '127.0.0.1' . $DISPLAY; +} + +if (my $pid = fork()) { + waitpid $pid, 0; + umount_all() == 0 or warn "umounting failed\n"; + $Xnest_pid and kill 15, $Xnest_pid; +} else { + $ENV{TERM} = 'linux'; # we only have terminfo for terminal "linux" + $ENV{HOME} = '/'; + # to kept sync with gi/mdk-stage1/init.c::env: + $ENV{LD_LIBRARY_PATH}='/lib:/usr/lib:/mnt/lib:/mnt/usr/lib:/usr/X11R6/lib:/mnt/usr/X11R6/lib:/lib64:/usr/lib64:/usr/X11R6/lib64:/mnt/lib64:/mnt/usr/lib64:/mnt/usr/X11R6/lib64'; + if ($remote_repository) { + $ENV{URLPREFIX} = $repository; + } + my $cmd = join(' ', "/usr/bin/runinstall2 --local_install", + if_($disk_iso_repository, "--method disk-iso"), + if_($remote_repository, "--method $remote_repository"), + @ARGV); + exec "$sudo chroot $SLASH_LOCATION $cmd" or die "exec $cmd in $SLASH_LOCATION failed\n"; +} + +sub system_verbose { warn join(' ', @_), "\n" if $verbose; system(@_) } +sub sys { &system_verbose; $? and die qq(running "@_" failed: $?\n) } + +sub mount_mdkinst { + my ($mdkinst) = @_; + sys("$sudo mount -t squashfs -o loop,ro $mdkinst $STAGE2_LOCATION"); +} +sub create_initial_symlinks() { + foreach (cat_or_die("$STAGE2_LOCATION/usr/share/symlinks")) { + my ($from, $to_) = split; + my $to = $SLASH_LOCATION . ($to_ || $from); + $from = "$STAGE2_LOCATION_ROOTED$from" if !$to_; + if (! -l $to) { + symlink $from, $to or die "symlinking $to failed\n"; + } + } +} + +sub create_initial_devices() { + sys("$sudo cp -a /dev/{mem,null,random,urandom} $SLASH_LOCATION/dev"); +} + +sub umount_all() { + my $err; + clean_stage2_updates(); + my @procs = ('/proc/bus/usb', '/proc', '/sys'); + foreach ((map { "$prefix_ROOTED$_" } @procs, ''), @procs, $STAGE2_LOCATION_ROOTED, $LOOP_MOUNT_POINT, $MEDIA_LOCATION_ROOTED, $IMAGE_LOCATION_ROOTED) { + my $dir = "$SLASH_LOCATION$_"; + rmdir $dir; + if (-d $dir) { + if (m!/proc/bus/usb! || begins_with($_, $prefix_ROOTED)) { + system_verbose "$sudo umount $dir 2>/dev/null"; + next; + } + system_verbose "$sudo umount $dir"; + } + rmdir $dir; + if (-d $dir) { + warn "$dir is busy\n"; + $err++; + } + } + if (my @remaining = cat_('/proc/mounts') =~ m!($SLASH_LOCATION/mnt/\S+)!g) { + warn "umount those mount points first: ", join(' ', @remaining), "\n"; + $err++; + } + $err; +} + +sub copy_auto_install_files() { + my ($opt); + each_index { + if ($opt eq 'auto_install' && -f $_) { + cp_f($_, $SLASH_LOCATION . $AUTO_INSTALL_ROOTED); + $_ = $AUTO_INSTALL_ROOTED; + } elsif ($opt eq 'defcfg' && -f $_) { + cp_f($_, $SLASH_LOCATION . $DEFCFG_ROOTED); + $_ = $DEFCFG_ROOTED; + } elsif ($opt eq 'rpmsrate' && -f $_) { + cp_f($_, $SLASH_LOCATION . $RPMSRATE_ROOTED); + } + undef $opt; + /^--?(.*)/ and $opt = $1; + } @ARGV; +} + +my @stage2_updates; +sub apply_stage2_updates() { + each_index { + if ($_ eq '--stage2-update') { + my $file = $ARGV[$::i+1]; + my $dest = $ARGV[$::i+2]; + if (-f $file && $dest) { + undef $_; + undef $ARGV[$::i+1]; + undef $ARGV[$::i+2]; + push @stage2_updates, $dest; + sys("$sudo mount --bind $file $STAGE2_LOCATION/$dest"); + } + } + } @ARGV; +} + +sub clean_stage2_updates() { + sys("$sudo umount $STAGE2_LOCATION/$_") foreach @stage2_updates; +} diff --git a/tools/extractchangelog b/tools/extractchangelog new file mode 100644 index 000000000..d838a0b68 --- /dev/null +++ b/tools/extractchangelog @@ -0,0 +1,2 @@ +#!/usr/bin/perl + diff --git a/tools/get-needed-drakx-modules b/tools/get-needed-drakx-modules new file mode 100755 index 000000000..019820c04 --- /dev/null +++ b/tools/get-needed-drakx-modules @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +use MDK::Common; + +my ($rel, $dest, $script) = @ARGV; + +$rel =~ s!/?$!!; + +foreach (`strace -efile perl -cw -I $rel $script 2>&1`) { + my ($f) = /^open\("(.*?)",.*\)\s*=\s*\d+$/ or next; + $f !~ m!/usr/lib/perl5/[^/]*/warnings.pm! or next; + if (begins_with($f, $rel)) { + print $f, "\t", $dest . substr($f, length($rel)), "\n"; + } elsif (begins_with($f, '/dev/')) { + # skip + } elsif (begins_with($f, '/')) { + print "$f\n"; + } +} diff --git a/tools/hd_grub.cgi b/tools/hd_grub.cgi new file mode 100755 index 000000000..ac55b6eaf --- /dev/null +++ b/tools/hd_grub.cgi @@ -0,0 +1,102 @@ +#!/usr/bin/perl + +use CGI ':all'; +use CGI::Carp; + +my $default_append = "ramdisk_size=128000 root=/dev/ram3"; +my $default_acpi = "acpi=ht"; +my $default_vga = "vga=788"; + +my $cgi_name = "/" . ($0 =~ m|([^/]+)$|)[0]; + +print + header(), + start_html(-TITLE => 'hd_grub configuration'); + +if (param()) { + print_menu_lst(); +} else { + print_form(); +} + +print end_html; + + +sub menu_lst { + my ($hd, $hd_linux, $partition_number, $directory) = @_; + + my $grub_partition_number = $partition_number - 1; + + <<EOF; +timeout 0 +default 0 + +title Mageia Install + +root ($hd,$grub_partition_number) +kernel $directory/isolinux/alt0/vmlinuz $default_append $default_acpi $default_vga automatic=method:disk,partition:$hd_linux$partition_number,directory:$directory +initrd $directory/isolinux/alt0/all.rdz +EOF + +} + +sub print_menu_lst { + my $directory = param('directory'); + $directory =~ s!^/!!; + print + ol(li(qq(Select the text below and save it in a file "menu.lst")), + li(qq(Create a floppy from $directory/images/hd_grub.img (eg: <tt>dd if=hd_grub.img of=/dev/fd0</tt>))), + li(qq(Copy the file "menu.lst" to the floppy, overwriting the existing one)), + ), + p(), + start_form(-name => 'form', -action => $cgi_name, -method => 'get'), + textarea(-default => menu_lst(param('hd'), param('hd_linux'), param('partition_number'), "/$directory"), + -rows => 15, -columns => 120, + ), + end_form(), +} + +sub print_form { + print + p(), + start_form(-name => 'form', -action => $cgi_name, -method => 'get'), + ul("Please choose the partition where %s is copied.", + li(popup_menu(-name => "hd", -default => 'hd0', + -values => [ 'hd0' .. 'hd3' ], + -labels => { hd0 => '1st BIOS hard drive (usually hda or sda)', + hd1 => '2nd BIOS hard drive', + hd2 => '3rd BIOS hard drive', + hd3 => '4th BIOS hard drive', + })), + li(popup_menu(-name => "hd_linux", -default => 'hda', + -values => [ 'hda' .. 'hdd', 'sda' .. 'sdc', 'hde' .. 'hdh' ], + -labels => { + hda => '1st IDE hard drive (hda)', + hdb => '2nd IDE hard drive (hdb)', + hdc => '3rd IDE hard drive (hdc)', + hdd => '4th IDE hard drive (hdd)', + hde => '5th IDE hard drive (hde)', + hdf => '6th IDE hard drive (hdf)', + hdg => '7th IDE hard drive (hdg)', + hdh => '8th IDE hard drive (hdh)', + sda => '1st SCSI hard drive (sda)', + sdb => '2nd SCSI hard drive (sdb)', + sdc => '3rd SCSI hard drive (sdc)', + })), + li(popup_menu(-name => "partition_number", -default => '0', + -values => [ 1 .. 15 ], + -labels => { 1 => '1st primary partition (hda1, sda1 or ...)', + 2 => '2nd primary partition', + 3 => '3rd primary partition', + 4 => '4th primary partition', + 5 => '5th partition (hda5, sda5 or ...) (first logical partition)', + map { $_ => $_ . 'th partition' } 6 .. 15 + })), + ), + p(), + ul("Please enter the directory containing the %s Distribution (relative to the partition chosen above)", + li(textfield(-name => 'directory', -default => '/cooker/i586', size => 40)), + ), + p(submit(-name => 'Go')), + end_form(); +} diff --git a/tools/install-xml-file-list b/tools/install-xml-file-list new file mode 100755 index 000000000..56b7a0a4f --- /dev/null +++ b/tools/install-xml-file-list @@ -0,0 +1,383 @@ +#!/usr/bin/perl + +use FileHandle; +use MDK::Common; +use XML::Parser; +use Data::Dumper; +use File::Glob; +use Config; +use Cwd 'cwd'; + +my $want_sudo = $ARGV[0] eq '--sudo' && shift @ARGV; + +@ARGV == 2 or die "usage: install-xml-file-list [--sudo] <xml file> <destination>\n"; +my ($xml_file_list, $DEST) = @ARGV; + +my $sudo = ''; +if ($>) { + $sudo = "sudo" if $want_sudo; + $ENV{PATH} = "/sbin:/usr/sbin:$ENV{PATH}"; +} + +#$verbose = 1; + +my $initial_dir = cwd(); +my $ARCH = arch() =~ /i.86/ ? 'i386' : arch(); +my $LIB = arch() =~ /x86_64/ ? "lib64" : "lib"; + +my $base_cpio_options = '-pumd --quiet'; + +my $problem; +my $tree = XML::Parser->new(Style => 'Tree')->parsefile($xml_file_list); + +my $main_node = decompose($tree); + +$main_node->{tag} eq 'list' or die "bad file $xml_file_list (main tag should be <list>)\n"; + +handle_nodes({}, $main_node); + +$problem and exit 1; + +install_needed_libraries(); + +final_cleanup(); + +sub error { + my ($err) = @_; + warn "FATAL: $err\n"; + $problem = 1; +} + +sub final_cleanup() { + #- cpio creates directory 700, that's not nice + system("find $DEST -type d -print0 | xargs -0 $sudo chmod 755"); +} + +sub handle_nodes { + my ($env, $e) = @_; + handle_node($env, decompose($_)) foreach @{$e->{l}}; +} +sub handle_node { + my ($env, $node) = @_; + + if (!$node->{tag} && $node->{text} !~ /\S/) { + } elsif (!$node->{tag}) { + install($env, $node->{text}); + } elsif ($node->{tag} eq 'if') { + my $cond = valid_cond($node->{attr}); + handle_nodes($env, $node) if $cond; + } elsif ($node->{tag} eq 'if-not') { + my $cond = valid_cond($node->{attr}); + handle_nodes($env, $node) if !$cond; + } elsif (member($node->{tag}, 'from', 'to', 'mode', 'filter')) { + handle_nodes(add_to_env($env, $node->{tag} => $node->{attr}), $node); + } else { + warn "expecting tag <from>, not <$node->{tag}>\n"; + } +} + +sub valid_cond { + my ($attr) = @_; + every { + if ($_ eq 'ARCH') { + $ARCH =~ /$attr->{$_}/; + } elsif ($_ eq 'set') { + $ENV{$attr->{$_}}; + } else { + die "<if>: unknown condition $_\n"; + } + } keys %$attr; +} + +sub add_to_env { + my ($env, $tag, $attr) = @_; + my %env = map_each { $::a => +{%$::b} } %$env; + foreach (keys %$attr) { + !$env{$tag}{$_} or die qq(overriding attribute <$tag $_="$env{$tag}{$_}"> with $_="$attr->{$_}"\n); + $env{$tag}{$_} = $attr->{$_}; + } + \%env; +} + +sub group_by_n { + my ($n, $l) = @_; + my (@r, $subl); + my $i = 0; + foreach (@$l) { + if ($i % $n == 0) { + push @r, $subl = []; + } + push @$subl, $_; + $i++; + } + @r; +} + +sub identify_file { + my ($dev, $ino) = @_; + "$dev:$ino"; +} + +sub all_files_rec_ { + my ($d) = @_; + + $d, -d $d && ! -l $d ? map { all_files_rec_("$d/$_") } all($d) : (); +} + +sub expand_macros { + my ($f) = @_; + $f =~ s!\bLIB\b!$LIB!g; + $f =~ s!\bARCH\b!$ARCH!ge; + $f =~ s!\$\((\w+)\)!$ENV{$1} || die "$1 undefined\n"!ge; + $f; +} + +my %needed_libraries; +sub collect_needed_libraries { + my (@to_check) = @_; + while (@to_check) { + my $to_check = join(' ', @to_check); + my @l = `ldd $to_check 2>/dev/null` =~ m! => (/\S+)!g; + foreach (@l) { + if ($main_node->{attr}{'no-arch-libraries'}) { + #- replace /lib/tls or /lib/i686 with /lib + s!^(/lib(64)?/).*?/!$1! if arch() !~ /x86_64/; + } + } + @to_check = grep { !$needed_libraries{$_}++ } @l; + @to_check = (); + } +} +sub install_needed_libraries { + copy_files('', $DEST, [ keys %needed_libraries ], '', '--dereference'); +} + +sub collect_needed_perl_files { + my ($local_rep, $dest, @scripts) = @_; + + my (%local, %global); + foreach my $script (@scripts) { + foreach (`strace -efile perl -cw -I$local_rep $script 2>&1`) { + my ($f) = /^open\("(.*?)",.*\)\s*=\s*\d+$/ or next; + if ($f =~ m!^\Q$local_rep\E/(.*)!) { + $local{$1} = 1; + } elsif (begins_with($f, '/dev/')) { + # skip + } elsif (begins_with($f, '/')) { + if ($main_node->{attr}{'no-arch-libraries'}) { + #- replace /lib/tls or /lib/i686 with /lib + $f =~ s!^(/lib(64)?/).*?/!$1! if arch() !~ /x86_64/; + } + $global{$f} = 1; + } + } + } + [ keys %local ], [ keys %global ]; +} + +sub copy_files { + my ($working_dir, $to_dir, $files, $b_flatten, @options) = @_; + + if ($b_flatten) { + mkdir_p($to_dir); + my $options = join(' ', '-r', @options); + foreach (group_by_n(20, $files)) { + warn "cp $options to_dir $to_dir from $working_dir: @$_\n" if $verbose; + system("cd $working_dir ; $sudo cp $options @$_ $to_dir"); + } + } else { + my $options = join(' ', $base_cpio_options, @options); + warn "cpio $options to_dir=$to_dir from=$working_dir: @$files\n" if $verbose; + open(my $F, "| cd $working_dir ; $sudo cpio $options $to_dir"); + print $F "$_\n" foreach @$files; + close($F) or die "cpio $to_dir failed\n"; + } +} + +sub install { + my ($env, $text) = @_; + + my $from_dir = expand_macros($env->{from}{dir}); + my $to_dir = $DEST . expand_macros($env->{to}{dir} || $env->{to}{flatten} && $from_dir || ''); + my $copy_mode = $env->{mode}{copy} || ''; + my $working_dir = '.'; + + my $expand = $env->{from}{expand} || ''; + + my $disallow_from_dir = sub { + !$from_dir or die "from dir not allowed with $expand binary\n"; + }; + + my $from_file = sub { + my ($rel, $b_full_glob, $b_recursive_dirs) = @_; + my $f = expand_macros($from_dir ? "$from_dir/$rel" : $rel); + my @l = $f; + chdir $working_dir; + if ($f =~ /\*/ || $b_full_glob) { + @l = File::Glob::bsd_glob($f); #- using bsd_glob because CORE::glob() splits on whitespace and we don't want this + if (@l == 0) { + error("no match for $f"); + } elsif (@l == 1 || $b_full_glob) { + } else { + error("multiple match for $f"); + @l = (); + } + } elsif (! -e $f) { + error("missing file $f ($rel) in $working_dir"); + @l = (); + } + if (@l == 1 && -d $l[0] && $b_recursive_dirs) { + @l = all_files_rec_($l[0]); + } + @l = grep { !m!/(\.svn|CVS)($|/)! } @l; + if (my $re = $env->{from}{matching}) { + @l = grep { eval $re } @l; + } + + collect_needed_libraries(grep { -f $_ && -x $_ } @l); + + chdir $initial_dir; + @l; + }; + + my @text_l = $env->{from}{spaces_in_filename} ? $text =~ /^\s*(.*?)\s*$/ : split(' ', $text); + my @files; + if ($expand eq 'tar') { + foreach (@text_l) { + my ($tarball) = $from_file->($_) or next; + system('tar', 'xfj', $tarball, '-C', $to_dir); + } + # not filling @files, things are already done + + } elsif ($expand eq 'command') { + @files = chomp_(`$text`); + + } elsif ($expand eq 'glob') { + #- glob done in $from_file + @files = @text_l; + + } elsif ($expand eq 'binary') { + $disallow_from_dir->(); + my @PATH = qw(/sbin /bin /usr/bin /usr/sbin /usr/X11R6/bin); + foreach my $name (map { expand_macros($_) } @text_l) { + my @l = grep { -x $_ } map { "$_/$name" } @PATH; + @l or error("can't find binary $name"), next; + if (@l > 1) { + my @m = grep { ! -l $_ } @l; + if (@m == 1) { + my $id = identify_file($m[0]); + push @files, grep { -l $_ && identify_file($_) eq $id } @l; + } + @l = @m if @m; + } + if (@l > 1) { + warn "many matches for binary $name: " . join(' ', @l) . ", choosing $l[0]\n"; + } + my $f = $l[0]; + while (1) { + push @files, $f; + $copy_mode ne 'dereference' or last; + my $l = readlink($f) or last; + if ($l =~ m!/! && $l !~ m!^\.\..*/s?bin/[^/]+$!) { + warn "keeping symlink $f -> $l as is\n"; + last; + } + $f = dirname($f) . '/' . $l; + } + } + $copy_mode ||= 'keep-links'; + $env->{filter}{command} ||= 'strip'; + + } elsif ($expand eq 'rpm') { + $disallow_from_dir->(); + foreach my $rpm (@text_l) { + my @l = chomp_(`rpm -ql $rpm`) or error("rpm $rpm must be installed"); + push @files, @l; + } + + } elsif ($expand eq 'perl') { + $disallow_from_dir->(); + $from_dir = '/usr/lib/perl5/vendor_perl/*'; + @files = @text_l; + } elsif ($expand eq 'main-perl') { + $disallow_from_dir->(); + $from_dir = $Config{privlib}; + @files = @text_l; + } elsif ($expand =~ /collect-perl-files/) { + my (undef, $local, $to) = split(' ', $expand); + + @files = @text_l; + warn "collect-perl-files $local $to @files ($env->{filter}{command})\n"; + my ($local_perl_files, $global_perl_files) = collect_needed_perl_files($local, $to, @files); + warn "collect-perl-files gave: ", join(' ', @$local_perl_files), "\n"; +# warn " and: ", join(' ', @$global_perl_files), "\n"; + copy_and_filter($local =~ m!/! ? $local : "$working_dir/$local", "$DEST$to", $local_perl_files, $env->{filter}, '', '--dereference'); + copy_and_filter('', $DEST, $global_perl_files, $env->{filter}, '', '--dereference'); + + } elsif ($expand) { + die "unknown expand method $expand\n"; + } else { + @files = @text_l; + + $env->{filter}{command} ||= 'strip' if $to_dir =~ m!/bin$!; + } + + if ($env->{to}{dir} && $from_dir) { + $working_dir = $from_dir; + undef $from_dir; + } + + my @all_files = map { $from_file->($_, $expand eq 'glob', $expand ne 'rpm') } @files; + + my @options = ( + if_($copy_mode ne 'keep-links', '--dereference'), + ); + if (@all_files) { + copy_and_filter($working_dir, $to_dir, \@all_files, $env->{filter}, $env->{to}{flatten}, @options); + } +} + +sub copy_and_filter { + my ($working_dir, $to_dir, $all_files, $filter, $flatten, @copy_options) = @_; + + copy_files($working_dir, $to_dir, $all_files, $flatten, @copy_options); + apply_filter($to_dir, $filter, $all_files, $flatten); +} + +sub apply_filter { + my ($to_dir, $filter, $all_files, $b_flatten) = @_; + + chdir $to_dir; + foreach (group_by_n(20, $all_files)) { + my @l = $b_flatten ? (map { basename($_) } @$_) : (map { "./$_" } @$_); + @l = grep { ! -d $_ } @l or next; + + if (my $subst = $filter->{subst}) { + system('perl', '-pi', '-e', $subst, @l); + } + if (my $command = $filter->{command}) { + $command = $initial_dir . "/$command" if $command =~ m!^..?/!; + if ($command =~ /simplify-drakx-modules/) { + @l = grep { !/\.so($|\.)/ } @l or next; + } + my @options = ( + if_($command eq 'gzip', '-9f'), + if_($command eq 'strip', '2>/dev/null'), + ); + warn "running $command @options @l\n" if $verbose; + system(join(' ', $command, @options, @l)); + } + } + chdir $initial_dir; +} + +sub decompose { + my ($tree) = @_; + my ($tag, $val) = @$tree; + if ($tag eq '0') { + { text => $val }; + } else { + my ($attr, @l) = @$val; + { tag => $tag, attr => $attr, l => [ group_by2(@l) ] }; + } +} diff --git a/tools/make_lang_png_transparent.c b/tools/make_lang_png_transparent.c new file mode 100644 index 000000000..9a037e864 --- /dev/null +++ b/tools/make_lang_png_transparent.c @@ -0,0 +1,167 @@ +/* + * Guillaume Cottenceau (gc at mandriva.com) + * + * Copyright 2002-2005 Mandriva + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#define PNG_DEBUG 3 +#include <png.h> + +void abort_(const char * s, ...) +{ + va_list args; + va_start(args, s); + vfprintf(stderr, s, args); + fprintf(stderr, "\n"); + va_end(args); + abort(); +} + +int x, y; + +int width, height; +png_byte color_type; +png_byte bit_depth; + +png_structp png_ptr; +png_infop info_ptr; +int number_of_passes; +png_bytep * row_pointers; + +void read_png_file(char* file_name) +{ + char header[8]; // 8 is the maximum size that can be checked + + /* open file and test for it being a png */ + FILE *fp = fopen(file_name, "rb"); + if (!fp) + abort_("[read_png_file] File %s could not be opened for reading", file_name); + fread(header, 1, 8, fp); + if (png_sig_cmp(header, 0, 8)) + abort_("[read_png_file] File %s is not recognized as a PNG file", file_name); + + + /* initialize stuff */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + abort_("[read_png_file] png_create_read_struct failed"); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + abort_("[read_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[read_png_file] Error during init_io"); + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + + width = info_ptr->width; + height = info_ptr->height; + color_type = info_ptr->color_type; + bit_depth = info_ptr->bit_depth; + + number_of_passes = png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + + + /* read file */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[read_png_file] Error during read_image"); + + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); + for (y=0; y<height; y++) + row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes); + + png_read_image(png_ptr, row_pointers); +} + + +void write_png_file(char* file_name) +{ + /* create file */ + FILE *fp = fopen(file_name, "wb"); + if (!fp) + abort_("[write_png_file] File %s could not be opened for writing", file_name); + + + /* initialize stuff */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + abort_("[write_png_file] png_create_write_struct failed"); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + abort_("[write_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during init_io"); + + png_init_io(png_ptr, fp); + + + /* write header */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during writing header"); + + png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + + /* write bytes */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during writing bytes"); + + png_write_image(png_ptr, row_pointers); + + + /* end write */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during end of write"); + + png_write_end(png_ptr, NULL); + +} + +void process_file(void) +{ + if (info_ptr->color_type != PNG_COLOR_TYPE_RGBA) + abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (is %d)", info_ptr->color_type); + + for (y=0; y<height; y++) { + png_byte* row = row_pointers[y]; + for (x=0; x<width; x++) { + png_byte* ptr = &(row[x*4]); + ptr[3] = 255-ptr[0]; + ptr[0] = ptr[1] = ptr[2] = 0; + } + } + +} + + +int main(int argc, char **argv) +{ + if (argc != 3) + abort_("Usage: program_name <file_in> <file_out>"); + + read_png_file(argv[1]); + process_file(); + write_png_file(argv[2]); +} diff --git a/tools/mdkinst_stage2_tool b/tools/mdkinst_stage2_tool new file mode 100755 index 000000000..c1ef5d151 --- /dev/null +++ b/tools/mdkinst_stage2_tool @@ -0,0 +1,66 @@ +#!/bin/sh + +error() { + cat <<EOF; +usage: mdkinst_stage2_tool [--clean] [--compress | --uncompress] <stage2 dir> [<compressed file>] +EOF + exit 1 +} + +if [ "$1" = "--clean" ]; then + CLEAN=1 + shift +fi + +[ $# = 2 -o $# = 3 ] || error + +if [ "$1" = "--compress" -o "$1" == "--uncompress" ]; then + ACTION=$1 + shift + STAGE2_DIR="$1" + shift + LIVE_DIR="$STAGE2_DIR/live" + if [ -n "$1" ]; then + COMPRESSED_IMAGE=$1 + shift + else + COMPRESSED_IMAGE="$STAGE2_DIR/mdkinst.sqfs" + fi +else + error +fi + +if [ $ACTION = "--compress" ]; then + which mksquashfs >/dev/null 2>/dev/null || { echo "missing command mksquashfs (from squashfs-tools)"; exit 1; } + + [ -d "$LIVE_DIR" ] || error + echo "Creating $COMPRESSED_IMAGE from $LIVE_DIR" + rm -f $STAGE2_DIR/.room + mksquashfs $LIVE_DIR $COMPRESSED_IMAGE -all-root -noappend >/dev/null || { echo "mksquashfs failed"; exit 1; } + chmod 755 $COMPRESSED_IMAGE + echo foo > $STAGE2_DIR/.room + if [ -s $STAGE2_DIR/.room ]; then + rm -f $STAGE2_DIR/.room + [ -n "$CLEAN" ] && rm -rf $LIVE_DIR + else + echo "not enough space" + rm -f $COMPRESSED_IMAGE + exit 1 + fi +else + which unsquashfs >/dev/null 2>/dev/null || { echo "missing command unsquashfs (from squashfs-tools)"; exit 1; } + + [ -f "$COMPRESSED_IMAGE" ] || error + echo "Creating $LIVE_DIR from $COMPRESSED_IMAGE" + + if [ $EUID != "0" ]; then + SUDO="sudo" + PATH="/sbin:/usr/sbin:$PATH" + fi + + unsquashfs -dest $LIVE_DIR $COMPRESSED_IMAGE || { rm -rf $LIVE_DIR; exit 1; } + + [ -n "$CLEAN" ] && rm -f $COMPRESSED_IMAGE +fi + +exit 0 diff --git a/tools/ntp_servers.pl b/tools/ntp_servers.pl new file mode 100644 index 000000000..d0a4b6cc2 --- /dev/null +++ b/tools/ntp_servers.pl @@ -0,0 +1,303 @@ +#!/usr/bin/perl + +#open F, "/usr/bin/lynx -dump http://www.eecis.udel.edu/~mills/ntp/clock1a.html|"; +open(my $G, "/usr/bin/lynx -dump http://www.eecis.udel.edu/~mills/ntp/clock2a.html|"); + +# Chris Kloiber <ckloiber@redhat.com> writes: +# > It's not considered polite to use the Stratum 1 servers for purposes that +# > are not absolutely critical. I would use Stratum 2 servers and live with +# > the few nanoseconds difference. +#parse() while <F>; + +parse($_) while <$G>; + +my @all; +my ($l, $nb); +sub parse { + local ($_) = @_; + /Active Servers/ .. /Discontinued Service/ or return; + if (/^\s+\d+\. ([A-Z ]*[A-Z]);?\s+([.\w-]+)/) { + push @all, $l = { name => $2, indic => $1 }; + $nb = 0; + } else { + s/^\s*//; + s/\s*$//; + my ($field, $val) = /^(.*):\s*(.*)/; + if ($field =~ /policy/i) { + $field = "policy"; + $val = lc join(' ', split(' ', $val)); + $val =~ s/glad to receive a note//; + $val =~ s/(but )?please send (a )?message to notify//; + $val =~ s/an email note is appreciated//; + $val =~ s/please send a message with the//; + $val =~ s/no need to notify//; + $val =~ s/[(), .;]*$//; + $val = "open access" if $val eq "public"; + warn "$val ($all[-1]{name})\n" if $val ne 'open access'; + } elsif ($field =~ /^Contact|Synchroni[sz]ation|Location|Geographic\s+Coordinates|Service\s+Area|Note$/i) { + } else { +# warn "bad line ($field) $_\n"; + return; + } + $l->{$field} .= ($l->{$field} && ' ') . $val; + } + $nb++; +} + + +use Data::Dumper; +#warn Dumper(\@all); + +foreach (grep { $_->{policy} eq 'open access' } @all) { + my ($country, $state) = split ' ', $_->{indic}; + $country = ucfirst(lc $country_codes{$country}); + $country .= " $state" if $state; + printf "\t'%s' => '%s',\n", lc($_->{name}), $country; +} + +BEGIN { +%country_codes = ( # from ftp://ftp.ripe.net/iso3166-countrycodes +"AF", "AFGHANISTAN", +"AL", "ALBANIA", +"DZ", "ALGERIA", +"AS", "AMERICAN SAMOA", +"AD", "ANDORRA", +"AO", "ANGOLA", +"AI", "ANGUILLA", +"AQ", "ANTARCTICA", +"AG", "ANTIGUA AND BARBUDA", +"AR", "ARGENTINA", +"AM", "ARMENIA", +"AW", "ARUBA", +"AU", "AUSTRALIA", +"AT", "AUSTRIA", +"AZ", "AZERBAIJAN", +"BS", "BAHAMAS", +"BH", "BAHRAIN", +"BD", "BANGLADESH", +"BB", "BARBADOS", +"BY", "BELARUS", +"BE", "BELGIUM", +"BZ", "BELIZE", +"BJ", "BENIN", +"BM", "BERMUDA", +"BT", "BHUTAN", +"BO", "BOLIVIA", +"BA", "BOSNIA AND HERZEGOWINA", +"BW", "BOTSWANA", +"BV", "BOUVET ISLAND", +"BR", "BRAZIL", +"IO", "BRITISH INDIAN OCEAN TERRITORY", +"BN", "BRUNEI DARUSSALAM", +"BG", "BULGARIA", +"BF", "BURKINA FASO", +"BI", "BURUNDI", +"KH", "CAMBODIA", +"CM", "CAMEROON", +"CA", "CANADA", +"CV", "CAPE VERDE", +"KY", "CAYMAN ISLANDS", +"CF", "CENTRAL AFRICAN REPUBLIC", +"TD", "CHAD", +"CL", "CHILE", +"CN", "CHINA", +"CX", "CHRISTMAS ISLAND", +"CC", "COCOS (KEELING) ISLANDS", +"CO", "COLOMBIA", +"KM", "COMOROS", +"CG", "CONGO", +"CD", "CONGO, THE DEMOCRATIC REPUBLIC OF THE", +"CK", "COOK ISLANDS", +"CR", "COSTA RICA", +"CI", "COTE D'IVOIRE", +"HR", "CROATIA", +"CU", "CUBA", +"CY", "CYPRUS", +"CZ", "CZECH REPUBLIC", +"DK", "DENMARK", +"DJ", "DJIBOUTI", +"DM", "DOMINICA", +"DO", "DOMINICAN REPUBLIC", +"TP", "EAST TIMOR", +"EC", "ECUADOR", +"EG", "EGYPT", +"SV", "EL SALVADOR", +"GQ", "EQUATORIAL GUINEA", +"ER", "ERITREA", +"EE", "ESTONIA", +"ET", "ETHIOPIA", +"FK", "FALKLAND ISLANDS (MALVINAS)", +"FO", "FAROE ISLANDS", +"FJ", "FIJI", +"FI", "FINLAND", +"FR", "FRANCE", +"FX", "FRANCE, METROPOLITAN", +"GF", "FRENCH GUIANA", +"PF", "FRENCH POLYNESIA", +"TF", "FRENCH SOUTHERN TERRITORIES", +"GA", "GABON", +"GM", "GAMBIA", +"GE", "GEORGIA", +"DE", "GERMANY", +"GH", "GHANA", +"GI", "GIBRALTAR", +"GR", "GREECE", +"GL", "GREENLAND", +"GD", "GRENADA", +"GP", "GUADELOUPE", +"GU", "GUAM", +"GT", "GUATEMALA", +"GN", "GUINEA", +"GW", "GUINEA-BISSAU", +"GY", "GUYANA", +"HT", "HAITI", +"HM", "HEARD AND MC DONALD ISLANDS", +"VA", "HOLY SEE (VATICAN CITY STATE)", +"HN", "HONDURAS", +"HK", "HONG KONG", +"HU", "HUNGARY", +"IS", "ICELAND", +"IN", "INDIA", +"ID", "INDONESIA", +"IR", "IRAN (ISLAMIC REPUBLIC OF)", +"IQ", "IRAQ", +"IE", "IRELAND", +"IL", "ISRAEL", +"IT", "ITALY", +"JM", "JAMAICA", +"JP", "JAPAN", +"JO", "JORDAN", +"KZ", "KAZAKHSTAN", +"KE", "KENYA", +"KI", "KIRIBATI", +"KP", "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF", +"KR", "KOREA, REPUBLIC OF", +"KW", "KUWAIT", +"KG", "KYRGYZSTAN", +"LA", "LAO PEOPLE'S DEMOCRATIC REPUBLIC", +"LV", "LATVIA", +"LB", "LEBANON", +"LS", "LESOTHO", +"LR", "LIBERIA", +"LY", "LIBYAN ARAB JAMAHIRIYA", +"LI", "LIECHTENSTEIN", +"LT", "LITHUANIA", +"LU", "LUXEMBOURG", +"MO", "MACAU", +"MK", "MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF", +"MG", "MADAGASCAR", +"MW", "MALAWI", +"MY", "MALAYSIA", +"MV", "MALDIVES", +"ML", "MALI", +"MT", "MALTA", +"MH", "MARSHALL ISLANDS", +"MQ", "MARTINIQUE", +"MR", "MAURITANIA", +"MU", "MAURITIUS", +"YT", "MAYOTTE", +"MX", "MEXICO", +"FM", "MICRONESIA, FEDERATED STATES OF", +"MD", "MOLDOVA, REPUBLIC OF", +"MC", "MONACO", +"MN", "MONGOLIA", +"MS", "MONTSERRAT", +"MA", "MOROCCO", +"MZ", "MOZAMBIQUE", +"MM", "MYANMAR", +"NA", "NAMIBIA", +"NR", "NAURU", +"NP", "NEPAL", +"NL", "NETHERLANDS", +"AN", "NETHERLANDS ANTILLES", +"NC", "NEW CALEDONIA", +"NZ", "NEW ZEALAND", +"NI", "NICARAGUA", +"NE", "NIGER", +"NG", "NIGERIA", +"NU", "NIUE", +"NF", "NORFOLK ISLAND", +"MP", "NORTHERN MARIANA ISLANDS", +"NO", "NORWAY", +"OM", "OMAN", +"PK", "PAKISTAN", +"PW", "PALAU", +"PA", "PANAMA", +"PG", "PAPUA NEW GUINEA", +"PY", "PARAGUAY", +"PE", "PERU", +"PH", "PHILIPPINES", +"PN", "PITCAIRN", +"PL", "POLAND", +"PT", "PORTUGAL", +"PR", "PUERTO RICO", +"QA", "QATAR", +"RE", "REUNION", +"RO", "ROMANIA", +"RU", "RUSSIA", +"RW", "RWANDA", +"KN", "SAINT KITTS AND NEVIS", +"LC", "SAINT LUCIA", +"VC", "SAINT VINCENT AND THE GRENADINES", +"WS", "SAMOA", +"SM", "SAN MARINO", +"ST", "SAO TOME AND PRINCIPE", +"SA", "SAUDI ARABIA", +"SN", "SENEGAL", +"SC", "SEYCHELLES", +"SL", "SIERRA LEONE", +"SG", "SINGAPORE", +"SK", "SLOVAKIA (Slovak Republic)", +"SI", "SLOVENIA", +"SB", "SOLOMON ISLANDS", +"SO", "SOMALIA", +"ZA", "SOUTH AFRICA", +"GS", "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS", +"ES", "SPAIN", +"LK", "SRI LANKA", +"SH", "ST. HELENA", +"PM", "ST. PIERRE AND MIQUELON", +"SD", "SUDAN", +"SR", "SURINAME", +"SJ", "SVALBARD AND JAN MAYEN ISLANDS", +"SZ", "SWAZILAND", +"SE", "SWEDEN", +"CH", "SWITZERLAND", +"SY", "SYRIAN ARAB REPUBLIC", +"TW", "TAIWAN, PROVINCE OF CHINA", +"TJ", "TAJIKISTAN", +"TZ", "TANZANIA, UNITED REPUBLIC OF", +"TH", "THAILAND", +"TG", "TOGO", +"TK", "TOKELAU", +"TO", "TONGA", +"TT", "TRINIDAD AND TOBAGO", +"TN", "TUNISIA", +"TR", "TURKEY", +"TM", "TURKMENISTAN", +"TC", "TURKS AND CAICOS ISLANDS", +"TV", "TUVALU", +"UG", "UGANDA", +"UA", "UKRAINE", +"AE", "UNITED ARAB EMIRATES", +"GB", "UNITED KINGDOM", +"US", "UNITED STATES", +"UM", "UNITED STATES MINOR OUTLYING ISLANDS", +"UY", "URUGUAY", +"UZ", "UZBEKISTAN", +"VU", "VANUATU", +"VE", "VENEZUELA", +"VN", "VIET NAM", +"VG", "VIRGIN ISLANDS (BRITISH)", +"VI", "VIRGIN ISLANDS (U.S.)", +"WF", "WALLIS AND FUTUNA ISLANDS", +"EH", "WESTERN SAHARA", +"YE", "YEMEN", +"YU", "YUGOSLAVIA", +"ZM", "ZAMBIA", +"ZW", "ZIMBABWE", + +#added +"UK", "UNITED KINGDOM", +); +} diff --git a/tools/rpcinfo-flushed.c b/tools/rpcinfo-flushed.c new file mode 100644 index 000000000..16303406d --- /dev/null +++ b/tools/rpcinfo-flushed.c @@ -0,0 +1,740 @@ +#define _(x) x + +/* @(#)rpcinfo.c 2.2 88/08/11 4.0 RPCSRC */ +#if !defined(lint) && defined (SCCSID) +static char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI"; +#endif + +/* + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +/* + * rpcinfo: ping a particular rpc program + * or dump the portmapper + */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include <getopt.h> +#include <string.h> +#include <unistd.h> +#include <rpc/rpc.h> +#include <stdio.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <signal.h> +#include <ctype.h> +#include <locale.h> +#include <libintl.h> + +#define MAXHOSTLEN 256 + +#define MIN_VERS ((u_long) 0) +#define MAX_VERS ((u_long) 4294967295UL) + +static void udpping (u_short portflag, int argc, char **argv); +static void tcpping (u_short portflag, int argc, char **argv); +static int pstatus (CLIENT *client, u_long prognum, u_long vers); +static void pmapdump (int argc, char **argv); +static bool_t reply_proc (void *res, struct sockaddr_in *who); +static void brdcst (int argc, char **argv) __attribute__ ((noreturn)); +static void deletereg (int argc, char **argv); +static void usage (void); +static u_long getprognum (char *arg); +static u_long getvers (char *arg); +static void get_inet_address (struct sockaddr_in *addr, char *host); + +/* + * Functions to be performed. + */ +#define NONE 0 /* no function */ +#define PMAPDUMP 1 /* dump portmapper registrations */ +#define TCPPING 2 /* ping TCP service */ +#define UDPPING 3 /* ping UDP service */ +#define BRDCST 4 /* ping broadcast UDP service */ +#define DELETES 5 /* delete registration for the service */ + +int +main (int argc, char **argv) +{ + register int c; + int errflg; + int function; + u_short portnum; + + setlocale (LC_ALL, ""); + + function = NONE; + portnum = 0; + errflg = 0; + while ((c = getopt (argc, argv, "ptubdn:")) != -1) + { + switch (c) + { + + case 'p': + if (function != NONE) + errflg = 1; + else + function = PMAPDUMP; + break; + + case 't': + if (function != NONE) + errflg = 1; + else + function = TCPPING; + break; + + case 'u': + if (function != NONE) + errflg = 1; + else + function = UDPPING; + break; + + case 'b': + if (function != NONE) + errflg = 1; + else + function = BRDCST; + break; + + case 'n': + portnum = (u_short) atoi (optarg); /* hope we don't get bogus # */ + break; + + case 'd': + if (function != NONE) + errflg = 1; + else + function = DELETES; + break; + + case '?': + errflg = 1; + } + } + + if (errflg || function == NONE) + { + usage (); + return 1; + } + + switch (function) + { + + case PMAPDUMP: + if (portnum != 0) + { + usage (); + return 1; + } + pmapdump (argc - optind, argv + optind); + break; + + case UDPPING: + udpping (portnum, argc - optind, argv + optind); + break; + + case TCPPING: + tcpping (portnum, argc - optind, argv + optind); + break; + + case BRDCST: + if (portnum != 0) + { + usage (); + return 1; + } + brdcst (argc - optind, argv + optind); + break; + + case DELETES: + deletereg (argc - optind, argv + optind); + break; + } + + return 0; +} + +static void +udpping (portnum, argc, argv) + u_short portnum; + int argc; + char **argv; +{ + struct timeval to; + struct sockaddr_in addr; + enum clnt_stat rpc_stat; + CLIENT *client; + u_long prognum, vers, minvers, maxvers; + int sock = RPC_ANYSOCK; + struct rpc_err rpcerr; + int failure; + + if (argc < 2 || argc > 3) + { + usage (); + exit (1); + } + prognum = getprognum (argv[1]); + get_inet_address (&addr, argv[0]); + /* Open the socket here so it will survive calls to clnt_destroy */ + sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) + { + perror ("rpcinfo: socket"); + exit (1); + } + failure = 0; + if (argc == 2) + { + /* + * A call to version 0 should fail with a program/version + * mismatch, and give us the range of versions supported. + */ + addr.sin_port = htons (portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create (&addr, prognum, (u_long) 0, + to, &sock)) == NULL) + { + clnt_pcreateerror ("rpcinfo"); + printf (_("program %lu is not available\n"), prognum); + exit (1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, + (char *) NULL, (xdrproc_t) xdr_void, + (char *) NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) + { + clnt_geterr (client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } + else if (rpc_stat == RPC_SUCCESS) + { + /* + * Oh dear, it DOES support version 0. + * Let's try version MAX_VERS. + */ + addr.sin_port = htons (portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create (&addr, prognum, MAX_VERS, + to, &sock)) == NULL) + { + clnt_pcreateerror ("rpcinfo"); + printf (_("program %lu version %lu is not available\n"), + prognum, MAX_VERS); + exit (1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, + NULL, (xdrproc_t) xdr_void, NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) + { + clnt_geterr (client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } + else if (rpc_stat == RPC_SUCCESS) + { + /* + * It also supports version MAX_VERS. + * Looks like we have a wise guy. + * OK, we give them information on all + * 4 billion versions they support... + */ + minvers = 0; + maxvers = MAX_VERS; + } + else + { + (void) pstatus (client, prognum, MAX_VERS); + exit (1); + } + } + else + { + (void) pstatus (client, prognum, (u_long) 0); + exit (1); + } + clnt_destroy (client); + for (vers = minvers; vers <= maxvers; vers++) + { + addr.sin_port = htons (portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create (&addr, prognum, vers, + to, &sock)) == NULL) + { + clnt_pcreateerror ("rpcinfo"); + printf (_("program %lu version %lu is not available\n"), + prognum, vers); + exit (1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, + NULL, (xdrproc_t) xdr_void, NULL, to); + if (pstatus (client, prognum, vers) < 0) + failure = 1; + clnt_destroy (client); + } + } + else + { + vers = getvers (argv[2]); + addr.sin_port = htons (portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create (&addr, prognum, vers, + to, &sock)) == NULL) + { + clnt_pcreateerror ("rpcinfo"); + printf (_("program %lu version %lu is not available\n"), + prognum, vers); + exit (1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL, + (xdrproc_t) xdr_void, NULL, to); + if (pstatus (client, prognum, vers) < 0) + failure = 1; + } + (void) close (sock); /* Close it up again */ + if (failure) + exit (1); +} + +static void +tcpping (portnum, argc, argv) + u_short portnum; + int argc; + char **argv; +{ + struct timeval to; + struct sockaddr_in addr; + enum clnt_stat rpc_stat; + CLIENT *client; + u_long prognum, vers, minvers, maxvers; + int sock = RPC_ANYSOCK; + struct rpc_err rpcerr; + int failure; + + if (argc < 2 || argc > 3) + { + usage (); + exit (1); + } + prognum = getprognum (argv[1]); + get_inet_address (&addr, argv[0]); + failure = 0; + if (argc == 2) + { + /* + * A call to version 0 should fail with a program/version + * mismatch, and give us the range of versions supported. + */ + addr.sin_port = htons (portnum); + if ((client = clnttcp_create (&addr, prognum, MIN_VERS, + &sock, 0, 0)) == NULL) + { + clnt_pcreateerror ("rpcinfo"); + printf (_("program %lu is not available\n"), prognum); + exit (1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, NULL, + (xdrproc_t) xdr_void, NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) + { + clnt_geterr (client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } + else if (rpc_stat == RPC_SUCCESS) + { + /* + * Oh dear, it DOES support version 0. + * Let's try version MAX_VERS. + */ + addr.sin_port = htons (portnum); + if ((client = clnttcp_create (&addr, prognum, MAX_VERS, + &sock, 0, 0)) == NULL) + { + clnt_pcreateerror ("rpcinfo"); + printf (_("program %lu version %lu is not available\n"), + prognum, MAX_VERS); + exit (1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, + NULL, (xdrproc_t) xdr_void, NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) + { + clnt_geterr (client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } + else if (rpc_stat == RPC_SUCCESS) + { + /* + * It also supports version MAX_VERS. + * Looks like we have a wise guy. + * OK, we give them information on all + * 4 billion versions they support... + */ + minvers = 0; + maxvers = MAX_VERS; + } + else + { + (void) pstatus (client, prognum, MAX_VERS); + exit (1); + } + } + else + { + (void) pstatus (client, prognum, MIN_VERS); + exit (1); + } + clnt_destroy (client); + (void) close (sock); + sock = RPC_ANYSOCK; /* Re-initialize it for later */ + for (vers = minvers; vers <= maxvers; vers++) + { + addr.sin_port = htons (portnum); + if ((client = clnttcp_create (&addr, prognum, vers, + &sock, 0, 0)) == NULL) + { + clnt_pcreateerror ("rpcinfo"); + printf (_("program %lu version %lu is not available\n"), + prognum, vers); + exit (1); + } + to.tv_usec = 0; + to.tv_sec = 10; + rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL, + (xdrproc_t) xdr_void, NULL, to); + if (pstatus (client, prognum, vers) < 0) + failure = 1; + clnt_destroy (client); + (void) close (sock); + sock = RPC_ANYSOCK; + } + } + else + { + vers = getvers (argv[2]); + addr.sin_port = htons (portnum); + if ((client = clnttcp_create (&addr, prognum, vers, &sock, + 0, 0)) == NULL) + { + clnt_pcreateerror ("rpcinfo"); + printf (_("program %lu version %lu is not available\n"), + prognum, vers); + exit (1); + } + to.tv_usec = 0; + to.tv_sec = 10; + rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL, + (xdrproc_t) xdr_void, NULL, to); + if (pstatus (client, prognum, vers) < 0) + failure = 1; + } + if (failure) + exit (1); +} + +/* + * This routine should take a pointer to an "rpc_err" structure, rather than + * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to + * a CLIENT structure rather than a pointer to an "rpc_err" structure. + * As such, we have to keep the CLIENT structure around in order to print + * a good error message. + */ +static int +pstatus (client, prognum, vers) + register CLIENT *client; + u_long prognum; + u_long vers; +{ + struct rpc_err rpcerr; + + clnt_geterr (client, &rpcerr); + if (rpcerr.re_status != RPC_SUCCESS) + { + clnt_perror (client, "rpcinfo"); + printf (_("program %lu version %lu is not available\n"), prognum, vers); + return -1; + } + else + { + printf (_("program %lu version %lu ready and waiting\n"), prognum, vers); + return 0; + } +} + +static void +pmapdump (argc, argv) + int argc; + char **argv; +{ + struct sockaddr_in server_addr; + register struct hostent *hp; + struct pmaplist *head = NULL; + int socket = RPC_ANYSOCK; + struct timeval minutetimeout; + register CLIENT *client; + struct rpcent *rpc; + + if (argc > 1) + { + usage (); + exit (1); + } + if (argc == 1) + get_inet_address (&server_addr, argv[0]); + else + { + bzero ((char *) &server_addr, sizeof server_addr); + server_addr.sin_family = AF_INET; + if ((hp = gethostbyname ("localhost")) != NULL) + bcopy (hp->h_addr, (caddr_t) & server_addr.sin_addr, + hp->h_length); + else + server_addr.sin_addr.s_addr = inet_addr ("0.0.0.0"); + } + minutetimeout.tv_sec = 60; + minutetimeout.tv_usec = 0; + server_addr.sin_port = htons (PMAPPORT); + if ((client = clnttcp_create (&server_addr, PMAPPROG, + PMAPVERS, &socket, 50, 500)) == NULL) + { + clnt_pcreateerror (_("rpcinfo: can't contact portmapper")); + exit (1); + } + if (clnt_call (client, PMAPPROC_DUMP, (xdrproc_t) xdr_void, NULL, + (xdrproc_t) xdr_pmaplist, (caddr_t) &head, + minutetimeout) != RPC_SUCCESS) + { + fputs (_("rpcinfo: can't contact portmapper"), stderr); + fputs (": ", stderr); + clnt_perror (client, "rpcinfo"); + exit (1); + } + if (head == NULL) + { + fputs (_("No remote programs registered.\n"), stdout); + } + else + { + fputs (_(" program vers proto port\n"), stdout); + for (; head != NULL; head = head->pml_next) + { + printf ("%10ld%5ld", + head->pml_map.pm_prog, + head->pml_map.pm_vers); + if (head->pml_map.pm_prot == IPPROTO_UDP) + printf ("%6s", "udp"); + else if (head->pml_map.pm_prot == IPPROTO_TCP) + printf ("%6s", "tcp"); + else + printf ("%6ld", head->pml_map.pm_prot); + printf ("%7ld", head->pml_map.pm_port); + rpc = getrpcbynumber (head->pml_map.pm_prog); + if (rpc) + printf (" %s\n", rpc->r_name); + else + printf ("\n"); + } + } +} + +/* + * reply_proc collects replies from the broadcast. + * to get a unique list of responses the output of rpcinfo should + * be piped through sort(1) and then uniq(1). + */ + +/*ARGSUSED */ +static bool_t +reply_proc (res, who) + void *res; /* Nothing comes back */ + struct sockaddr_in *who; /* Who sent us the reply */ +{ + register struct hostent *hp; + + hp = gethostbyaddr ((char *) &who->sin_addr, sizeof who->sin_addr, + AF_INET); + printf ("%s %s\n", inet_ntoa (who->sin_addr), + (hp == NULL) ? _("(unknown)") : hp->h_name); + fflush(stdout); + return FALSE; +} + +static void +brdcst (argc, argv) + int argc; + char **argv; +{ + enum clnt_stat rpc_stat; + u_long prognum, vers; + + if (argc != 2) + { + usage (); + exit (1); + } + prognum = getprognum (argv[0]); + vers = getvers (argv[1]); + rpc_stat = clnt_broadcast (prognum, vers, NULLPROC, (xdrproc_t) xdr_void, + NULL, (xdrproc_t) xdr_void, NULL, + (resultproc_t) reply_proc); + if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) + { + fprintf (stderr, _("rpcinfo: broadcast failed: %s\n"), + clnt_sperrno (rpc_stat)); + exit (1); + } + exit (0); +} + +static void +deletereg (argc, argv) + int argc; + char **argv; +{ + u_long prog_num, version_num; + + if (argc != 2) + { + usage (); + exit (1); + } + if (getuid ()) + { /* This command allowed only to root */ + fputs (_("Sorry. You are not root\n"), stderr); + exit (1); + } + prog_num = getprognum (argv[0]); + version_num = getvers (argv[1]); + if ((pmap_unset (prog_num, version_num)) == 0) + { + fprintf (stderr, _("rpcinfo: Could not delete registration for prog %s version %s\n"), + argv[0], argv[1]); + exit (1); + } +} + +static void +usage () +{ + fputs (_("Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"), + stderr); + fputs (_(" rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"), + stderr); + fputs (_(" rpcinfo -p [ host ]\n"), stderr); + fputs (_(" rpcinfo -b prognum versnum\n"), stderr); + fputs (_(" rpcinfo -d prognum versnum\n"), stderr); +} + +static u_long +getprognum (arg) + char *arg; +{ + register struct rpcent *rpc; + register u_long prognum; + + if (isalpha (*arg)) + { + rpc = getrpcbyname (arg); + if (rpc == NULL) + { + fprintf (stderr, _("rpcinfo: %s is unknown service\n"), arg); + exit (1); + } + prognum = rpc->r_number; + } + else + { + prognum = (u_long) atoi (arg); + } + + return prognum; +} + +static u_long +getvers (arg) + char *arg; +{ + register u_long vers; + + vers = (int) atoi (arg); + return vers; +} + +static void +get_inet_address (addr, host) + struct sockaddr_in *addr; + char *host; +{ + register struct hostent *hp; + + bzero ((char *) addr, sizeof *addr); + addr->sin_addr.s_addr = (u_long) inet_addr (host); + if (addr->sin_addr.s_addr == INADDR_NONE + || addr->sin_addr.s_addr == INADDR_ANY) + { + if ((hp = gethostbyname (host)) == NULL) + { + fprintf (stderr, _("rpcinfo: %s is unknown host\n"), + host); + exit (1); + } + bcopy (hp->h_addr, (char *) &addr->sin_addr, hp->h_length); + } + addr->sin_family = AF_INET; +} diff --git a/tools/serial_probe/Makefile b/tools/serial_probe/Makefile new file mode 100644 index 000000000..86deb49f9 --- /dev/null +++ b/tools/serial_probe/Makefile @@ -0,0 +1,13 @@ +CFLAGS = -Wall -Os +CFILES = $(wildcard *.c) +OFILES = $(CFILES:%.c=%.o) +GOAL = serial_probe + +$(GOAL): $(OFILES) + +serial.o: serial.c serial.h device.h kudzu.h +serial_probe.o: serial_probe.c serial.h device.h +serial_probe: serial_probe.o + +clean: + rm -f $(GOAL) $(OFILES) *~ diff --git a/tools/serial_probe/device.h b/tools/serial_probe/device.h new file mode 100644 index 000000000..58d1414a0 --- /dev/null +++ b/tools/serial_probe/device.h @@ -0,0 +1,104 @@ +/* Copyright 1999-2003 Red Hat, Inc. + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#ifndef _KUDZU_DEVICES_H_ +#define _KUDZU_DEVICES_H_ + +#include <stdio.h> + +enum deviceClass { + /* device classes... this is somewhat ad-hoc */ + CLASS_UNSPEC = ~0, + CLASS_OTHER = (1 << 0), + CLASS_NETWORK = (1 << 1), + CLASS_SCSI = (1 << 2), + CLASS_MOUSE = (1 << 3), + CLASS_AUDIO = (1 << 4), + CLASS_CDROM = (1 << 5), + CLASS_MODEM = (1 << 6), + CLASS_VIDEO = (1 << 7), + CLASS_TAPE = (1 << 8), + CLASS_FLOPPY = (1 << 9), + CLASS_SCANNER = (1 << 10), + CLASS_HD = (1 << 11), + CLASS_RAID = (1 << 12), + CLASS_PRINTER = (1 << 13), + CLASS_CAPTURE = (1 << 14), + CLASS_KEYBOARD = (1 << 15), + CLASS_MONITOR = (1 << 16), + CLASS_USB = (1 << 17), + CLASS_SOCKET = (1 << 18), + CLASS_FIREWIRE = (1 << 19), + CLASS_IDE = (1 << 20) +}; + +/* Update this if needed */ +#define CLASS_LAST CLASS_IDE + +enum deviceBus { + /* 'bus' that a device is attached to... this is also ad-hoc */ + /* BUS_SBUS is sort of a misnomer - it's more or less Sun */ + /* OpenPROM probing of all various associated non-PCI buses */ + BUS_UNSPEC = ~0, + BUS_OTHER = (1 << 0), + BUS_PCI = (1 << 1), + BUS_SBUS = (1 << 2), + BUS_SERIAL = (1 << 3), + BUS_PSAUX = (1 << 4), + BUS_PARALLEL = (1 << 5), + BUS_SCSI = (1 << 6), + BUS_IDE = (1 << 7), + /* Again, misnomer */ + BUS_KEYBOARD = (1 << 8), + BUS_DDC = (1 << 9), + BUS_USB = (1 << 10), + BUS_ISAPNP = (1 << 11), + BUS_MISC = (1 << 12), + BUS_FIREWIRE = (1 << 13), + BUS_PCMCIA = (1 << 14), + BUS_ADB = (1 << 15), + BUS_MACIO = (1 << 16) +}; + +struct device { + /* This pointer is used to make lists by the library. */ + /* Do not expect it to remain constant (or useful) across library calls. */ + struct device *next; + /* Used for ordering, and for aliasing (modem0, modem1, etc.) */ + int index; + enum deviceClass type; /* type */ + enum deviceBus bus; /* bus it's attached to */ + char * device; /* device file associated with it */ + char * driver; /* driver to load, if any */ + char * desc; /* a description */ + int detached; /* should we care if it disappears? */ + struct device *(*newDevice) (struct device *old, struct device *new); + void (*freeDevice) (struct device *dev); + void (*writeDevice) (FILE *file, struct device *dev); + int (*compareDevice) (struct device *dev1, struct device *dev2); +}; + +struct device *newDevice(struct device *old, struct device *new); +void freeDevice(struct device *dev); +void writeDevice(FILE *file, struct device *dev); +int compareDevice(struct device *dev1, struct device *dev2); +struct device *readDevice(FILE *file); + +/* Most of these aren't implemented yet...... */ +/* Return everything found, even non-useful stuff */ +#define PROBE_ALL 1 +/* Don't do 'dangerous' probes that could do weird things (isapnp, serial) */ +#define PROBE_SAFE (1<<1) +/* Stop at first device found */ +#define PROBE_ONE (1<<2) + +#endif diff --git a/tools/serial_probe/kudzu.h b/tools/serial_probe/kudzu.h new file mode 100644 index 000000000..f96565cca --- /dev/null +++ b/tools/serial_probe/kudzu.h @@ -0,0 +1,26 @@ +/* Copyright 1999-2003 Red Hat, Inc. + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _KUDZU_H_ +#define _KUDZU_H_ + +/* kudzu: it grows on you */ + +/* level of debugging output */ +#undef DEBUG_LEVEL + +#ifdef DEBUG_LEVEL +#define DEBUG(s...) fprintf(stderr,s) +#else +#define DEBUG(s...) ; +#endif + +#endif diff --git a/tools/serial_probe/serial.c b/tools/serial_probe/serial.c new file mode 100644 index 000000000..c84cbcff5 --- /dev/null +++ b/tools/serial_probe/serial.c @@ -0,0 +1,1136 @@ +/* Copyright 1999-2003 Red Hat, Inc. + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * probe serial port for PnP/Legacy devices + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <termios.h> +#include <errno.h> +#include <string.h> +#include <signal.h> +#include <time.h> +#include <libgen.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/sysmacros.h> + +#include <asm/types.h> +#include <linux/serial.h> + +#include "serial.h" +#include "kudzu.h" + +/* character strings ARE null-terminated in the following structure */ +/* these elements are marked with a (string) in the comment */ +/* If PnP device sent 6 bit data stream, we've xlated by a 0x20 offset */ +/* When computing checksum, must remove this offset */ +struct pnp_com_id { + unsigned char xlate_6bit; /* does this contain xlated data */ + unsigned char other_id[17]; /* backward compatibility with pre-PNP */ + unsigned char other_len; /* length of the other_id */ + unsigned char pnp_rev[2]; /* PnP revision bytes */ + unsigned char pnp_rev_str[8]; /* PnP revision (string version) */ + unsigned char eisa_id[4]; /* EISA Mfr identifier (string) */ + unsigned char product_id[5]; /* Mfr determined product ID (string) */ + unsigned char serial_number[9];/* Optional dev serial number (string) */ + unsigned char class_name[33]; /* Optional PnP Class name (string) */ + unsigned char driver_id[42]; /* Optional compat device IDs (string) */ + unsigned char user_name[42]; /* Optional verbose product descr (string)*/ + unsigned char checksum[2]; /* Optional checksum */ +}; + +/* there are two possible bytes to signify the start of a PnP ID string */ +#define BeginPnP1 0x28 +#define BeginPnP2 0x08 + +/* Likewise, two possible stop bytes */ +#define EndPnP1 0x29 +#define EndPnP2 0x09 + +/* these chars indicate extensions to the base dev id exist */ +#define ExtendPnP1 0x5c +#define ExtendPnP2 0x3c + +#define PNP_COM_MAXLEN 256 + +/* results from initiating hardware probe of a hardware device */ +#define PNP_COM_FATAL 1 /* system error, check errno */ +#define PNP_COM_FAIL 2 /* probe ok, but found nothing */ +#define PNP_COM_OK 3 /* probe ok, we found it */ + +/* types of devices we might find */ +/* if PNP_COM_PNPDEV is NOT set, its a legacy device */ +#define PNP_COM_MOUSE 1 /* its a mouse */ +#define PNP_COM_MODEM 2 /* its a modem */ +#define PNP_COM_OTHER 4 /* device is there, cant tell what kind */ +#define PNP_COM_NOEXIST 8 /* no device seen */ +#define PNP_COM_PNPDEV 512 /* its a PNP device */ + +static void serialFreeDevice(struct serialDevice *dev) { + if (dev->pnpmfr) free(dev->pnpmfr); + if (dev->pnpmodel) free(dev->pnpmodel); + if (dev->pnpcompat) free(dev->pnpcompat); + if (dev->pnpdesc) free(dev->pnpdesc); + freeDevice((struct device *)dev); +} + +static void serialWriteDevice(FILE *file, struct serialDevice *dev) +{ + writeDevice(file, (struct device *) dev); + if (dev->pnpmfr) + fprintf(file,"pnpmfr: %s\n",dev->pnpmfr); + if (dev->pnpmodel) + fprintf(file,"pnpmodel: %s\n",dev->pnpmodel); + if (dev->pnpcompat) + fprintf(file,"pnpcompat: %s\n",dev->pnpcompat); + if (dev->pnpdesc) + fprintf(file,"pnpdesc: %s\n",dev->pnpdesc); +} + +static int serialCompareDevice( struct serialDevice *dev1, struct serialDevice *dev2) +{ + int x; + + x = compareDevice((struct device *)dev1, (struct device *)dev2); + if (x && x!=2) return x; + if (dev1->pnpmfr && dev2->pnpmfr && strcmp(dev1->pnpmfr,dev2->pnpmfr)) + return 1; + if ((!dev1->pnpmfr || !dev2->pnpmfr) && (dev1->pnpmfr != dev2->pnpmfr)) + return 1; + if (dev1->pnpmodel && dev2->pnpmodel && strcmp(dev1->pnpmodel,dev2->pnpmodel)) + return 1; + if ((!dev1->pnpmodel || !dev2->pnpmodel) && (dev1->pnpmodel != dev2->pnpmodel)) + return 1; + if (dev1->pnpcompat && dev2->pnpcompat && strcmp(dev1->pnpcompat,dev2->pnpcompat)) + return 1; + if ((!dev1->pnpcompat || !dev2->pnpcompat) && (dev1->pnpcompat != dev2->pnpcompat)) + return 1; + if (dev1->pnpdesc && dev2->pnpdesc && strcmp(dev1->pnpdesc,dev2->pnpdesc)) + return 1; + if ((!dev1->pnpdesc || !dev2->pnpdesc) && (dev1->pnpdesc != dev2->pnpdesc)) + return 1; + return x; +} + + +struct serialDevice * serialNewDevice(struct serialDevice *dev) { + struct serialDevice *ret; + + ret = malloc(sizeof(struct serialDevice)); + memset(ret,'\0',sizeof(struct serialDevice)); + ret=(struct serialDevice *)newDevice((struct device *)dev,(struct device *)ret); + ret->bus = BUS_SERIAL; + ret->newDevice = serialNewDevice; + ret->freeDevice = serialFreeDevice; + ret->writeDevice = serialWriteDevice; + ret->compareDevice = serialCompareDevice; + if (dev && dev->bus == BUS_SERIAL) { + if (dev->pnpmfr) + ret->pnpmfr=strdup(dev->pnpmfr); + if (dev->pnpmodel) + ret->pnpmodel=strdup(dev->pnpmodel); + if (dev->pnpcompat) + ret->pnpcompat=strdup(dev->pnpcompat); + if (dev->pnpdesc) + ret->pnpdesc=strdup(dev->pnpdesc); + } + return ret; +} + +/* + * wait_input - wait until there is data available on fd, + * for the length of time specified by *timo (indefinite + * if timo is NULL). + */ + +static int wait_for_input (int fd, struct timeval *timo) { + fd_set ready; + int n; + + FD_ZERO(&ready); + FD_SET(fd, &ready); + + n = select(fd+1, &ready, NULL, &ready, timo); + return n; +} + +static int open_serial_port( char *port ) { + int fd; + + DEBUG("opening serial port %s...", port); + + fd = open( port, O_RDWR | O_NONBLOCK); + if (fd < 0) { + DEBUG("failed.\n"); + return -1; + } else { + DEBUG("successful.\n"); + } + + /* reset file so it is no longer in non-blocking mode */ + if (fcntl(fd, F_SETFL, 0) < 0) { + close(fd); + DEBUG("Failed to set port to non-blocking mode\n"); + return -1; + } + + return fd; +} + +/* <0 means ioctl error occurred */ +static int get_serial_lines( int fd ) { + int modem_lines; + + ioctl(fd, TIOCMGET, &modem_lines); + return modem_lines; +} + +/* <0 means ioctl error occurred */ +static int set_serial_lines( int fd, int modem_lines ) { + return ioctl(fd, TIOCMSET, &modem_lines); +} + +/* set serial port to 1200 baud, 'nbits' bits, 1 stop, no parity */ +static int setup_serial_port( int fd, int nbits, struct termios *attr ) { + + DEBUG("setting up serial port\n"); + + attr->c_iflag = IGNBRK | IGNPAR; + attr->c_cflag = 0; + attr->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | PARENB); + attr->c_cflag |= CREAD | CLOCAL; /*| CRTSCTS ; */ + if (nbits == 7) + attr->c_cflag |= CS7 | CSTOPB; + else + attr->c_cflag |= CS8; + attr->c_oflag = 0; + attr->c_lflag = 0; + + attr->c_cc[VMIN] = 1; + attr->c_cc[VTIME] = 5; + + if (cfsetospeed( attr, B1200)) + return -1; + if (cfsetispeed( attr, B1200)) + return -1; + return tcsetattr(fd, TCSANOW, attr); +} + +/* Initialize the serial port to a known state *before* probing. This is + * apparently required for some Logitech mice, who will stubbornly refuse + * to respond to PnP probes after they've been opened by gpm or XFree. + */ + +static int init_port(int fd) { + struct termios attr; + + if (tcgetattr(fd,&attr)) + return 1; + + cfsetospeed(&attr, B2400); + cfsetispeed(&attr, B2400); + attr.c_iflag = IXON | ICRNL; + attr.c_cflag = CLOCAL | HUPCL | CREAD | B9600 | CS8; + attr.c_oflag = 0; + attr.c_lflag = 0; + return tcsetattr(fd, TCSANOW, &attr); +} + + +/* Request for PnP info from serial device */ +/* See page 6 of the pnpcom doc from Microsoft */ +/* Return code tells us what happened */ +/* */ +/* PNP_COM_FATAL - error, errno has reason */ +/* PNP_COM_OK - probe initiated successfully */ +static int init_pnp_com_seq1( int fd ) { + int modem_lines; + int temp; + int dsr_status; + int rc = PNP_COM_OK; + struct termios portattr; + + DEBUG("initializing 1st PNP sequence\n"); + if (init_port(fd)) + return PNP_COM_FATAL; + + modem_lines = get_serial_lines(fd); + + /* COM port initialization, check for device enumerate */ + + /* turn on DTR, turn off RTS */ + modem_lines |= TIOCM_DTR; + modem_lines &= ~TIOCM_RTS; + set_serial_lines(fd, modem_lines); + + /* wait 200ms for DSR=1 */ + usleep(200000); + + dsr_status = get_serial_lines(fd) & TIOCM_DSR; + /* see if we got DSR coming up */ + + if (!dsr_status) { + DEBUG("Device did not set DSR\n"); + } + + /* COM port Setup, 1st phase */ + temp = tcgetattr(fd, &portattr); + if (temp < 0) + return PNP_COM_FATAL; + + /* now we set port to be 1200 baud, 7 bits, no parity, 1 stop bit */ + temp = setup_serial_port( fd, 7, &portattr ); + if (temp < 0) + return PNP_COM_FATAL; + + /* we drop DTR and RTS */ + modem_lines &= ~( TIOCM_RTS | TIOCM_DTR); + set_serial_lines(fd, modem_lines); + usleep(200000); + + /* bring DTR back up */ + modem_lines |= TIOCM_DTR; + set_serial_lines(fd, modem_lines); + usleep(200000); + + /* Wait for response, 1st phase */ + modem_lines |= TIOCM_RTS; + set_serial_lines(fd, modem_lines); + /* usleep(200000); => AQ: not valid as we should look to receive data during this time!! */ + + return rc; +} + + +/* Request for PnP info from serial device */ +/* See page 6 of the pnpcom doc from Microsoft */ +/* Always returns PNP_COM_OK */ +static int init_pnp_com_seq2( int fd ) { + int modem_lines; + int rc = PNP_COM_OK; + + DEBUG("initializing 2nd PNP sequence\n"); + + modem_lines = get_serial_lines(fd); + + /* COM port setup, 2nd phase */ + /* turn off DTR and RTS */ + modem_lines &= ~(TIOCM_DTR | TIOCM_RTS); + set_serial_lines(fd, modem_lines); + usleep(200000); + + /* wait for response, 2nd phase */ + /* turn on DTR and RTS */ + modem_lines |= (TIOCM_DTR | TIOCM_RTS); + set_serial_lines(fd, modem_lines); + /* usleep(200000); => AQ: not valid as we should look to receive data during this time!! */ + + return rc; +} + + +/* Request for PnP info from serial modem device */ +/* Uses ATI9 code, may not do anything but return 'ERROR' */ +/* Return code tells us what happened */ +/* */ +/* PNP_COM_FATAL - error, errno has reason */ +/* PNP_COM_OK - probe initiated successfully */ +/* PNP_COM_FAIL - DSR never came on - try alterntives */ +/* means (ATI9?) to get PnP string */ +static int init_pnp_com_ati9( int fd ) { + int modem_lines; + int temp; + int done; + int respindex; + int starttime; + unsigned char resp[100], buf[2]; + struct timeval timo; + struct termios portattr; + + DEBUG("Querying ATI9 info from modem\n"); + modem_lines = get_serial_lines(fd); + + /* turn off RTS */ + modem_lines &= ~TIOCM_RTS; + set_serial_lines(fd, modem_lines); + + /* wait 200ms for DSR=1 */ + usleep(200000); + + /* now we set port to be 1200 baud, 8 bits, no parity, 1 stop bit */ + temp = tcgetattr(fd, &portattr); + if (temp < 0) { + modem_lines |= TIOCM_DTR | TIOCM_RTS; + set_serial_lines(fd, modem_lines); + return PNP_COM_FATAL; + } + + /* goto 1200 baud, 8 bits */ + temp = setup_serial_port( fd, 8, &portattr ); + if (temp < 0) { + modem_lines |= TIOCM_DTR | TIOCM_RTS; + set_serial_lines(fd, modem_lines); + return PNP_COM_FATAL; + } + + /* turn on DTR and RTS */ + modem_lines = get_serial_lines(fd); + modem_lines |= TIOCM_RTS | TIOCM_DTR; + set_serial_lines(fd, modem_lines); + usleep(200000); + + /* send the 'AT' command */ + DEBUG("Sending ATI9 command to modem\n"); + + write(fd, "ATI9\r", 5); + + /* start reading - read the AT command back */ + done = 0; + respindex= 0; + starttime=time(NULL); + memset(resp, 0, sizeof(resp)); + while (!done) { + timo.tv_sec=0; + timo.tv_usec=250000; + if (wait_for_input(fd, &timo) > 0) { + temp = read( fd, buf, 1 ); + if (temp < 0) { + if (errno != EAGAIN) + return PNP_COM_FATAL; + } else { + resp[respindex++] = buf[0]; + resp[respindex] = 0; + } + } else + done = 1; + + /* shouldnt run more than 5 seconds */ + if (time(NULL)-starttime > 5 ) + done = 1; + + if (respindex > 6) + done = 1; + + if (strstr(resp, "ATI9\r")) + done = 1; + + DEBUG("ATI9 probe ->%d \"%s\"\n",respindex, resp); + } + + /* see if we saw the 'OK' response */ + if (strstr(resp, "(")) + return PNP_COM_OK; + else + return PNP_COM_FAIL; + + return PNP_COM_OK; +} + +/* See if this is a legacy mouse device */ +/* Only called if the PnP probe above failed */ +/* We turn off the mouse via RS232 lines, then turn it on */ +/* If it spits out an 'M' character (at 1200 baud, 7N1) */ +/* it could be a mouse. */ +/* */ +/* Return code tells us what happened */ +/* */ +/* PNP_COM_FATAL - error, errno has reason */ +/* PNP_COM_OK - probe saw 'M' */ +/* PNP_COM_FAIL - Never saw the 'M' response */ + +static int find_legacy_mouse( int fd ) { + int modem_lines; + int temp; + int done; + int starttime; + unsigned char resp[2]; + struct timeval timo; + struct termios portattr; + + DEBUG("looking for a legacy mouse\n"); + + /* now we set port to be 1200 baud, 7 bits, no parity, 1 stop bit */ + temp = tcgetattr(fd, &portattr); + if (temp < 0) + return PNP_COM_FATAL; + + /* goto 1200 baud, etc etc*/ + temp = setup_serial_port( fd, 7, &portattr ); + if (temp < 0) + return PNP_COM_FATAL; + + /* we drop DTR and RTS */ + modem_lines = get_serial_lines(fd); + modem_lines &= ~( TIOCM_RTS | TIOCM_DTR); + set_serial_lines(fd, modem_lines); + usleep(200000); + + /* bring them DTR back up */ + modem_lines |= TIOCM_DTR | TIOCM_RTS; + set_serial_lines(fd, modem_lines); + + /* start reading - after first character we quit */ + done = 0; + starttime=time(NULL); + while (!done) { + timo.tv_sec=0; + timo.tv_usec=250000; + if (wait_for_input(fd, &timo) > 0) { + temp = read( fd, resp, 1 ); + if (temp < 0) { + if (errno != EAGAIN) + return PNP_COM_FATAL; + } else { + done = 1; + } + } else + done = 1; + + + /* shouldnt run more than 2 seconds */ + if (time(NULL)-starttime > 2 ) + done = 1; + } + if (*resp == 'M') { + DEBUG("Found legacy mouse\n"); + return PNP_COM_OK; + } else + return PNP_COM_FAIL; +} + +/* See if this is a legacy modem device */ +/* Only called if the PnP probe above failed */ +/* We send a '!AT' and see if we get an 'OK' back */ +/* */ +/* Return code tells us what happened */ +/* */ +/* PNP_COM_FATAL - error, errno has reason */ +/* PNP_COM_OK - probe saw 'OK' */ +/* PNP_COM_FAIL - Never saw the 'OK' response */ +static int find_legacy_modem( int fd ) { + int modem_lines; + int temp; + int done; + int respindex; + int starttime; + unsigned char resp[10], buf[2]; + struct timeval timo; + struct termios portattr; + + DEBUG("looking for a legacy modem\n"); + + /* now we set port to be 1200 baud, 8 bits, no parity, 1 stop bit */ + temp = tcgetattr(fd, &portattr); + if (temp < 0) + return PNP_COM_FATAL; + + /* goto 1200 baud, 8 bits */ + temp = setup_serial_port( fd, 8, &portattr ); + if (temp < 0) + return PNP_COM_FATAL; + + /* turn on DTR and RTS */ + modem_lines = get_serial_lines(fd); + modem_lines |= TIOCM_RTS | TIOCM_DTR; + set_serial_lines(fd, modem_lines); + usleep(200000); + + /* send the 'AT' command */ + DEBUG("Sending AT command to modem\n"); + + write(fd, "AT\r", 3); + + /* start reading - we'll get AT command back first, then modem response */ + done = 0; + respindex= 0; + starttime=time(NULL); + memset(resp, 0, sizeof(resp)); + while (!done) { + timo.tv_sec=0; + timo.tv_usec=250000; + if (wait_for_input(fd, &timo) > 0) { + temp = read( fd, buf, 1 ); + if (temp < 0) { + if (errno != EAGAIN) + return PNP_COM_FATAL; + } else { + resp[respindex++] = buf[0]; + } + } else + done = 1; + + /* shouldnt run more than 5 seconds */ + if (time(NULL)-starttime > 5 ) + done = 1; + + if (respindex > 9) + done = 1; + } + + /* see if we saw the 'OK' response */ + if (strstr(resp, "OK")) + return PNP_COM_OK; + else + return PNP_COM_FAIL; +} + +/* retrieve the PnP ID string */ +/* timeout after 3 seconds */ +/* should probably set a 200 msec timeout per char, as spec says */ +/* if no char received, we're done */ +static int read_pnp_string( int fd, unsigned char *pnp_string, int *pnp_len, int pnp_stringbuf_size ) { + int pnp_index; + int temp, done, counter; + int seen_start; + time_t starttime; + struct timeval timo; + unsigned char buf[80]; + unsigned char end_char; + + DEBUG("Attempting to read PNP ID string\n"); + + /* see if we have any input waiting */ + pnp_index = 0; + seen_start = 0; + done = 0; + end_char = 0; + starttime=time(NULL); + while (!done) { + timo.tv_sec=0; + timo.tv_usec=250000; + if (wait_for_input(fd, &timo) > 0) { + temp = read( fd, buf, 1 ); + if (temp < 0) { + if (errno != EAGAIN) + return PNP_COM_FAIL; + } else { + for (counter=0; counter < temp; counter++) { + pnp_string[pnp_index++] = buf[counter]; + if (seen_start) { + if (buf[counter] == end_char) { + done=1; + break; + } + } else { + if (buf[counter] == BeginPnP1) { + seen_start = 1; + end_char = EndPnP1; + } else if (buf[counter] == BeginPnP2) { + seen_start = 1; + end_char = EndPnP2; + } + } + } + } + } else + done = 1; + + /* shouldnt run more than 3 seconds */ + if (time(NULL)-starttime > 3 ) + done = 1; + + if (pnp_index >= pnp_stringbuf_size) + done = 1; + } + pnp_string[pnp_index] = 0; + *pnp_len=pnp_index; + if(*pnp_len > 0) + return PNP_COM_OK; + else /* allows to call seq2 to be conformant */ + return PNP_COM_FAIL; +} + +/* parse the PnP ID string into components */ +static int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, + struct pnp_com_id *pnp_id ) { + unsigned char *p1, *p2; + unsigned char *start; + unsigned char *end; + unsigned char *curpos; + unsigned char *endfield; + unsigned char *temppos; + unsigned char *pnp_string; + unsigned char end_char; + + int no_more_extensions=0; + int stage; + int len; + unsigned short int checksum; + char hex_checksum[5]; + + char extension_delims[] = {EndPnP1, EndPnP2, ExtendPnP1, ExtendPnP2, 0}; + char end_delims[] = {EndPnP1, EndPnP2, 0}; + unsigned char* p1end = NULL; + unsigned char* p2end = NULL; + + /* clear out pnp_id */ + memset(pnp_id, 0, sizeof(*pnp_id)); + + /* copy pnp_string to temp space */ + pnp_string = alloca(pnp_len+1); + memcpy(pnp_string, pnp_id_string, pnp_len+1); + + /* first find the start of the PnP part of string */ + p1 = memchr( pnp_string, BeginPnP1, pnp_len ); + p2 = memchr( pnp_string, BeginPnP2, pnp_len ); + + + if (p1) { + int p_len = pnp_len - (p1 - pnp_string); + p1end = memchr(p1, EndPnP1, p_len); + } + if (p2) { + int p_len = pnp_len - (p2 - pnp_string); + p2end = memchr(p2, EndPnP2, p_len); + } + + /* use the one which points nearest to start of the string */ + /* and is actually defined */ + if ( p1 && p1end && p2 && p2end ) { + start = (p1 < p2) ? p1 : p2; + } else if ( p1 && p1end ) + start = p1; + else if ( p2 && p2end ) + start = p2; + else + start = NULL; + + /* if no start then we're done */ + if (!start) + return -1; + + /* the length of the initial part cannot be more than 17 bytes */ + if ((start - pnp_string) > 17) + return -1; + + /* setup end character we are looking for based on the start character */ + if (start == p2) { + pnp_id->xlate_6bit = 1; + end_char = EndPnP2; + /* we need to xlate data in PnP fields */ + /* remember to skip the revision fields (bytes 1 and 2 after start) */ + temppos=start; + while (1) { + if (*temppos == EndPnP2) { + *temppos += 0x20; + break; + } else if (temppos != start+1 && temppos != start+2 ) + *temppos += 0x20; + + temppos++; + } + } else { + pnp_id->xlate_6bit = 0; + end_char = EndPnP1; + } + + /* move everything before the start of the PnP block */ + memcpy(pnp_id->other_id, pnp_string, start-pnp_string); + pnp_id->other_len = start - pnp_string; + + /* now we get the PnP fields - all were zero'd out above */ + curpos = start+1; + memcpy(pnp_id->pnp_rev,curpos,2); curpos += 2; + memcpy(pnp_id->eisa_id,curpos,3); curpos += 3; + memcpy(pnp_id->product_id,curpos,4); curpos += 4; + /* now we see if have extension fields */ + no_more_extensions = 0; + stage = 0; + while (!no_more_extensions) { + if (*curpos == ExtendPnP1 || *curpos == ExtendPnP2) { + curpos++; + endfield = strpbrk(curpos, extension_delims); + if (!endfield) + return -1; + /* if we reached the end of all PnP data, back off */ + /* cause there is a checksum at the end of extension data */ + if (*endfield == EndPnP1 || *endfield == EndPnP2) + endfield -= 2; + } else + break; + + len = endfield - curpos; + switch (stage) { + case 0: + if (len != 8 && len != 0 ) + return -1; + + memcpy(pnp_id->serial_number,curpos,len); + curpos += len; + break; + + case 1: + if (len > 33) + return -1; + memcpy(pnp_id->class_name, curpos, len); + curpos = endfield; + break; + + case 2: + if (len > 41) + return -1; + memcpy(pnp_id->driver_id, curpos, len); + curpos = endfield; + break; + + case 3: + if (len > 41) + return -1; + memcpy(pnp_id->user_name, curpos, len); + curpos = endfield; + break; + } + stage++; + } + + /* now find the end of all PnP data */ + end = strpbrk(curpos, end_delims); + if (!end) + return -1; + + /* if we had any extensions, we expect an checksum */ + if (stage != 0) { + /* copy checksum into struct */ + memcpy(pnp_id->checksum, curpos, 2); + + /* compute the checksum as the sum of all PnP bytes, excluding */ + /* the two byte checksum. */ + checksum = 0; + for (temppos=start; temppos <= end; temppos++) { + /* skip checksum in calculation */ + if (temppos == (end-2) || temppos == (end-1)) + continue; + /* dont xlate the revision at start */ + if (temppos != (start+1) && temppos != (start+2)) + checksum += *temppos - ((pnp_id->xlate_6bit) ? 0x20 : 0); + else + checksum += *temppos; + } + sprintf(hex_checksum, "%.2X", checksum & 0xff); + if (strncmp(hex_checksum, pnp_id->checksum, 2)) + return -1; + } + + /* checksum was ok, so we're done */ + return 0; +} + +static int attempt_pnp_retrieve(int fd, char *pnp_string, int *pnp_strlen, int pnp_stringbuf_size) { + int pnp_probe_status; + struct pnp_com_id pnp_id; + int tried_at_prodding=0, give_up=0; + + DEBUG("Attempting PNP information retrieval\n"); + + while (!give_up) { + pnp_probe_status = init_pnp_com_seq1(fd); + if (pnp_probe_status == PNP_COM_FATAL) + return PNP_COM_FATAL; + pnp_probe_status = read_pnp_string(fd, pnp_string, pnp_strlen, + pnp_stringbuf_size); + if (pnp_probe_status == PNP_COM_FAIL) { + init_pnp_com_seq2(fd); /* always succeeds */ + + pnp_probe_status = read_pnp_string(fd, pnp_string, pnp_strlen, + pnp_stringbuf_size); + } + + if (*pnp_strlen == 1 && pnp_string[0] == 'M') /* legacy mouse */ + return PNP_COM_OK; + /* see if we got anything useful, if not try AT command */ + /* to prod device into correct serial params */ + if (parse_pnp_string( pnp_string, *pnp_strlen, &pnp_id )<0) { + DEBUG("That failed.\n"); + if (!tried_at_prodding) { + DEBUG("Prod modem with AT command.\n"); + write(fd, "AT\r", 3); + tried_at_prodding=1; + } else + give_up = 1; + } else + return PNP_COM_OK; + } + + /* normal PNP detection has failed. */ + /* try sending a ATI9 code to the modem to see if we get PnP id back */ + init_pnp_com_ati9(fd); + read_pnp_string(fd, pnp_string, pnp_strlen, pnp_stringbuf_size ); + if (parse_pnp_string( pnp_string, *pnp_strlen, &pnp_id )<0) { + *pnp_strlen = 0; + pnp_string[0] = 0; + return PNP_COM_FAIL; + } else + return PNP_COM_OK; +} + +struct device *serialProbe(enum deviceClass probeClass, int probeFlags, + struct device *devlist) { + int fd; + int temp; + int pnp_strlen; + int devicetype=-1; + unsigned char pnp_string[100]; + char port[20]; + struct termios origattr; + struct pnp_com_id pnp_id; + struct serialDevice *serdev; + struct stat sb; + int maj, twelve=12; + int console=-1; + int stdin_line=-1; + struct serial_struct si; + + DEBUG("Probing for serial ports\n"); + + if (probeFlags & PROBE_SAFE) return devlist; + + /* Are we on a serial console? */ + fstat(0,&sb); + maj = major(sb.st_rdev); + if (maj != 4 && (maj < 136 || maj > 143)) { + if (ioctl (0, TIOCLINUX, &twelve) < 0) { + if (ioctl (0, TIOCGSERIAL, &si) >= 0) { + if (si.line > 0) { + stdin_line = 1 << si.line; + } else { + stdin_line = 0; + } + } else stdin_line = 0; + } + } + + fd=open("/dev/console",O_RDWR); + if (fd != -1) { + fstat(fd,&sb); + maj = major(sb.st_rdev); + if (maj != 4 && (maj < 136 || maj > 143)) { + if (ioctl (fd, TIOCLINUX, &twelve) < 0) { + #ifdef __powerpc__ + // we could have gotten an error for another reason - like EINVAL + // skipping ttyS0 on PPC - which is where most modems reside + if (errno == ENOTTY) { + #endif + if (ioctl (fd, TIOCGSERIAL, &si) >= 0) { + if (si.line > 0) { + console = 1 << si.line; + } else { + console = 0; + #ifdef __powerpc__ + } + #endif + } + } else console = 0; + } + } + close(fd); + } + + + if ( + (probeClass & CLASS_UNSPEC) || + (probeClass & CLASS_OTHER) || + (probeClass & CLASS_MOUSE) || + (probeClass & CLASS_MODEM) || + (probeClass & CLASS_PRINTER) + ) { + int x; + + for (x=0; x<=3 ; x++) { + struct stat sbuf; + char lockfile[32]; + if (x==console || x==stdin_line) continue; + snprintf(port,20,"/dev/ttyS%d",x); + + /* Make sure it's not in use */ + snprintf(lockfile,32,"/var/lock/LCK..ttyS%d",x); + if (!stat(lockfile,&sbuf)) { + DEBUG("Port %s in use, skipping probe.\n", + port); + continue; + } + memset(lockfile,'\0',32); + if (readlink("/dev/modem",lockfile,32)>0) { + if (!strcmp(basename(port),basename(lockfile))) { + snprintf(lockfile,32,"/var/lock/LCK..modem"); + if (!stat(lockfile,&sbuf)) { + DEBUG("Port %s in use, skipping probe.\n", + port); + continue; + } + } + } + + if ((fd=open_serial_port(port)) < 0) { + continue; + } + /* save the current state of the port */ + temp = tcgetattr(fd, &origattr); + if (temp < 0) { + DEBUG("unable to retrieve port attributes...no port present?\n"); + close(fd); + continue; + } + + + /* try twiddling RS232 control lines and see if it talks to us */ + devicetype=-1; + pnp_strlen = 0; + if (attempt_pnp_retrieve( fd, pnp_string, &pnp_strlen, + sizeof(pnp_string) - 1 ) == PNP_COM_FATAL) + goto endprobe; + + /* see if we found any PnP signature */ + if (pnp_strlen != 0 && (pnp_strlen != 1 || pnp_string[0] != 'M')) { + + /* fill in the PnP com structure */ + if (parse_pnp_string( pnp_string, pnp_strlen, &pnp_id )<0) { + DEBUG("Got PNP data back, but failed to parse. Aborting\n"); + goto endprobe; + } else { + char *foo; + int len; + + DEBUG("PNP data parsed.\n"); + serdev = serialNewDevice(NULL); + + if (pnp_id.user_name[0]) { + serdev->pnpdesc = strdup(pnp_id.user_name); + len = strlen(pnp_id.eisa_id) + + strlen(pnp_id.product_id) + + strlen(pnp_id.user_name) + 3; + foo = malloc(len); + snprintf(foo,len,"%s|%s %s",pnp_id.eisa_id, + pnp_id.product_id,pnp_id.user_name); + } else { + len = strlen(pnp_id.eisa_id) + + strlen(pnp_id.product_id) + 3; + foo = malloc(len); + snprintf(foo,len,"%s|%s",pnp_id.eisa_id, + pnp_id.product_id); + } + if (serdev->desc) free(serdev->desc); + serdev->desc=strdup(foo); + serdev->device=strdup(port+5); + if (serdev->driver) free(serdev->driver); + serdev->driver=strdup("ignore"); + serdev->pnpmfr = strdup(pnp_id.eisa_id); + serdev->pnpmodel = strdup(pnp_id.product_id); + + free(foo); + foo=pnp_id.product_id; + if (pnp_id.driver_id) { + if (strstr(pnp_id.driver_id,"PNP")) + foo = strstr(pnp_id.driver_id,"PNP")+3; + serdev->pnpcompat = strdup(pnp_id.driver_id); + } + + if (*pnp_id.other_id == 'M' || + !strncmp(pnp_id.class_name, "MOUSE", 5) || + !strncmp(foo, "0F", 2)) { + serdev->type = CLASS_MOUSE; + if (!strncmp(serdev->desc, "|", 1)) { + free(serdev->desc); + serdev->desc=strdup("Generic Serial Mouse"); + } + if (serdev->driver) free(serdev->driver); + serdev->driver = strdup("generic"); + } + else if (!strncmp(pnp_id.class_name, "MODEM", 5) || + !strncmp(foo, "C", 1)) + serdev->type = CLASS_MODEM; + else if (!strncmp(pnp_id.class_name, "PRINTER", 7)) + serdev->type = CLASS_PRINTER; + else + serdev->type = CLASS_OTHER; + if (serdev->type & probeClass) { + if (devlist) + serdev->next = devlist; + devlist = (struct device *)serdev; + if (probeFlags & PROBE_ONE) { + tcsetattr(fd, TCSANOW, &origattr); + tcflush(fd, TCIOFLUSH); + close(fd); + return devlist; + } + } else { + serdev->freeDevice(serdev); + } + goto endprobe; + } + } else { + DEBUG("No PNP data received.\n"); + /* try to find a legacy device */ + + temp = find_legacy_mouse(fd); + if (temp == PNP_COM_FATAL) { + goto endprobe; + } else if (temp == PNP_COM_OK) { + if (probeClass & CLASS_MOUSE) { + serdev=serialNewDevice(NULL); + serdev->type = CLASS_MOUSE; + serdev->device = strdup(port+5); + serdev->driver= strdup("generic"); + serdev->desc = strdup("Generic Serial Mouse"); + if (devlist) + serdev->next = devlist; + devlist = (struct device *)serdev; + if (probeFlags & PROBE_ONE) { + tcsetattr(fd, TCSANOW, &origattr); + tcflush(fd, TCIOFLUSH); + close(fd); + return devlist; + } + } + goto endprobe; + } else { + DEBUG("Didn't see a legacy mouse.\n"); + + temp = find_legacy_modem(fd); + if (temp == PNP_COM_FATAL) { + goto endprobe; + } else if (temp == PNP_COM_OK) { + DEBUG("Legacy modem signature seen.\n"); + if (probeClass & CLASS_MODEM) { + serdev=serialNewDevice(NULL); + serdev->type = CLASS_MODEM; + serdev->device = strdup(port+5); + serdev->driver= strdup("ignore"); + serdev->desc = strdup("Generic Serial Modem"); + if (devlist) + serdev->next = devlist; + devlist = (struct device *)serdev; + if (probeFlags & PROBE_ONE) { + tcsetattr(fd, TCSANOW, &origattr); + tcflush(fd, TCIOFLUSH); + close(fd); + return devlist; + } + } + goto endprobe; + } else { + DEBUG("Didnt see a legacy modem, game over.\n"); + } + } + } + endprobe: + DEBUG("Restoring original port attributes\n"); + tcsetattr(fd, TCSANOW, &origattr); + tcflush(fd, TCIOFLUSH); + close(fd); + } + } + return devlist; +} diff --git a/tools/serial_probe/serial.h b/tools/serial_probe/serial.h new file mode 100644 index 000000000..691abeb26 --- /dev/null +++ b/tools/serial_probe/serial.h @@ -0,0 +1,43 @@ +/* Copyright 1999-2003 Red Hat, Inc. + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _KUDZU_SERIAL_H_ +#define _KUDZU_SERIAL_H_ + +#include "device.h" + +struct serialDevice { + /* common fields */ + struct device *next; /* next device in list */ + int index; + enum deviceClass type; /* type */ + enum deviceBus bus; /* bus it's attached to */ + char * device; /* device file associated with it */ + char * driver; /* driver to load, if any */ + char * desc; /* a description */ + int detached; + /* serial-specific fields */ + struct serialDevice *(*newDevice) (struct serialDevice *dev); + void (*freeDevice) (struct serialDevice *dev); + void (*writeDevice) (FILE *file, struct serialDevice *dev); + int (*compareDevice) (struct serialDevice *dev1, struct serialDevice *dev2); + char * pnpmfr; + char * pnpmodel; + char * pnpcompat; + char * pnpdesc; + +}; + +struct serialDevice *serialNewDevice(struct serialDevice *dev); +struct device *serialProbe(enum deviceClass probeClass, int probeFlags, + struct device *devlist); + +#endif diff --git a/tools/serial_probe/serial_probe.c b/tools/serial_probe/serial_probe.c new file mode 100644 index 000000000..a9aae52e5 --- /dev/null +++ b/tools/serial_probe/serial_probe.c @@ -0,0 +1,114 @@ +/* Copyright 1999 Mandrakesoft <fpons@mandrakesoft.com> + * + * The following file used by this one are copyrighted by RedHat and + * are taken from kudzu : + * device.h + * serial.h + * serial.c + * This file is taken from kudzu.c copyrighted by RedHat, 1999. + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "serial.h" +#include "device.h" + +typedef struct device *(newFunc)(struct device *); +typedef int (initFunc)(); +typedef struct device *(probeFunc)(enum deviceClass, int, struct device *); + +char *classStrings[] = { + "UNSPEC", "OTHER", "NETWORK", "SCSI", "VIDEO", "AUDIO", + "MOUSE", "MODEM", "CDROM", "TAPE", "FLOPPY", "SCANNER", + "HD", "RAID", "PRINTER", "CAPTURE", "KEYBOARD", NULL +}; + +struct device *newDevice(struct device *old, struct device *new) { + if (!old) { + if (!new) { + new = malloc(sizeof(struct device)); + memset(new,'\0',sizeof(struct device)); + } + new->type = CLASS_UNSPEC; + } else { + new->type = old->type; + if (old->device) new->device = strdup(old->device); + if (old->driver) new->driver = strdup(old->driver); + if (old->desc) new->desc = strdup(old->desc); + } + new->newDevice = newDevice; + new->freeDevice = freeDevice; + new->compareDevice = compareDevice; + return new; +} + +void freeDevice(struct device *dev) { + if (!dev) { + printf("freeDevice(null)\n"); + abort(); /* return; */ + } + if (dev->device) free (dev->device); + if (dev->driver) free (dev->driver); + if (dev->desc) free (dev->desc); + free (dev); +} + +void writeDevice(FILE *file, struct device *dev) {} +int compareDevice(struct device *dev1, struct device *dev2) { return 0; } + +int main () { + struct device* devices = NULL; + struct serialDevice* serialDevice = NULL; + + devices = serialProbe(CLASS_UNSPEC, 0, devices); + while (devices) { + serialDevice = (struct serialDevice*)devices; + + printf("CLASS="); + if (serialDevice->type == CLASS_UNSPEC) puts("UNSPEC"); else + if (serialDevice->type == CLASS_OTHER) puts("OTHER"); else + if (serialDevice->type == CLASS_NETWORK) puts("NETWORK"); else + if (serialDevice->type == CLASS_SCSI) puts("SCSI"); else + if (serialDevice->type == CLASS_MOUSE) puts("MOUSE"); else + if (serialDevice->type == CLASS_AUDIO) puts("AUDIO"); else + if (serialDevice->type == CLASS_CDROM) puts("CDROM"); else + if (serialDevice->type == CLASS_MODEM) puts("MODEM"); else + if (serialDevice->type == CLASS_VIDEO) puts("VIDEO"); else + if (serialDevice->type == CLASS_TAPE) puts("TAPE"); else + if (serialDevice->type == CLASS_FLOPPY) puts("FLOPPY"); else + if (serialDevice->type == CLASS_SCANNER) puts("SCANNER"); else + if (serialDevice->type == CLASS_HD) puts("HD"); else + if (serialDevice->type == CLASS_RAID) puts("RAID"); else + if (serialDevice->type == CLASS_PRINTER) puts("PRINTER"); else + if (serialDevice->type == CLASS_CAPTURE) puts("CAPTURE"); else + if (serialDevice->type == CLASS_KEYBOARD) puts("KEYBOARD"); else + if (serialDevice->type == CLASS_MONITOR) puts("MONITOR"); else + if (serialDevice->type == CLASS_USB) puts("USB"); else + if (serialDevice->type == CLASS_SOCKET) puts("SOCKET"); else + if (serialDevice->type == CLASS_FIREWIRE) puts("FIREWIRE"); else + if (serialDevice->type == CLASS_IDE) puts("IDE"); + printf("BUS=SERIAL\n"); + printf("DEVICE=/dev/%s\n", serialDevice->device); + printf("DRIVER=%s\n", serialDevice->driver); + if (!serialDevice->pnpdesc) printf("DESCRIPTION=%s\n", serialDevice->desc); + if (serialDevice->pnpmfr) printf("MANUFACTURER=%s\n", serialDevice->pnpmfr); + if (serialDevice->pnpmodel) printf("MODEL=%s\n", serialDevice->pnpmodel); + if (serialDevice->pnpcompat) printf("COMPAT=%s\n", serialDevice->pnpcompat); + if (serialDevice->pnpdesc) printf("DESCRIPTION=%s\n", serialDevice->pnpdesc); + printf("\n"); + + devices=devices->next; + } + + return 0; +} diff --git a/tools/shift_all.pl b/tools/shift_all.pl new file mode 100644 index 000000000..88abfa0e1 --- /dev/null +++ b/tools/shift_all.pl @@ -0,0 +1,113 @@ +use MDK::Common; + +my %shifts = ( +'af' => 1, +'am' => 1, +'ar' => 0, +'az' => 1, +'be' => 2, +'bg' => 2, +'bn' => 1, +'br' => 2, +'bs' => 2, +'ca' => 2, +'cs' => 2, +'cy' => 2, +'da' => 2, +'de' => 2, +'el' => 2, +'en_GB' => 2, +'en_US' => 2, +'eo' => 2, +'es' => 2, +'et' => 2, +'eu' => 2, +'fa' => 0, +'fi' => 1, +'fo' => 2, +'fr' => 2, +'ga' => 2, +'gd' => 2, +'gl' => 2, +'gv' => 2, +'he' => 0, +'hi' => 1, +'hr' => 2, +'hu' => 2, +'hy' => 1, +'ia' => 2, +'id' => 1, +'is' => 1, +'it' => 1, +'iu' => 1, +'ja' => 3, +'ka' => 1, +'kn' => 1, +'ko' => 1, +'kw' => 0, +'lo' => 0, +'lt' => 0, +'lv' => 0, +'mi' => 0, +'mk' => 0, +'mn' => 0, +'mr' => 0, +'ms' => 0, +'mt' => 0, +'nb' => 0, +'nl' => 0, +'nn' => 0, +'no' => 0, +'oc' => 0, +'pl' => 0, +'pt_BR' => 0, +'pt' => 0, +'ro' => 0, +'ru' => 0, +'sk' => 0, +'sl' => 0, +'sp' => 0, +'sq' => 0, +'sr' => 0, +'sv' => 0, +'ta' => 1, +'te' => 1, +'tg' => 0, +'th' => 0, +'tr' => 0, +'tt' => 1, +'uk' => 0, +'ur' => 1, +'uz' => 0, +'vi' => 0, +'wa' => 0, +'yi' => 0, +'zh_CN' => 0, +'zh_TW' => 0, +); + +foreach (glob("lang*.png")) { + /lang-(.*)\.png/; + exists $shifts{$1} or die "doesn't exist for $_"; + $shifts{$1} or next; + print "./a.out $_ l.png $shifts{$1}\n"; + system("./a.out $_ l.png $shifts{$1}"); + renamef('l.png', $_); +} + + + + + + + + + + + + + + + + + diff --git a/tools/shift_img.c b/tools/shift_img.c new file mode 100644 index 000000000..36cb53e48 --- /dev/null +++ b/tools/shift_img.c @@ -0,0 +1,165 @@ +/* + * Guillaume Cottenceau (gc at mandriva.com) + * + * Copyright 2002-2005 Mandriva + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#define PNG_DEBUG 3 +#include <png.h> + +void abort_(const char * s, ...) +{ + va_list args; + va_start(args, s); + vfprintf(stderr, s, args); + fprintf(stderr, "\n"); + va_end(args); + abort(); +} + +int x, y; + +int width, height; +png_byte color_type; +png_byte bit_depth; + +png_structp png_ptr; +png_infop info_ptr; +int number_of_passes; +png_bytep * row_pointers; + +void read_png_file(char* file_name) +{ + char header[8]; // 8 is the maximum size that can be checked + + /* open file and test for it being a png */ + FILE *fp = fopen(file_name, "rb"); + if (!fp) + abort_("[read_png_file] File %s could not be opened for reading", file_name); + fread(header, 1, 8, fp); + if (png_sig_cmp(header, 0, 8)) + abort_("[read_png_file] File %s is not recognized as a PNG file", file_name); + + + /* initialize stuff */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + abort_("[read_png_file] png_create_read_struct failed"); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + abort_("[read_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[read_png_file] Error during init_io"); + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + + width = info_ptr->width; + height = info_ptr->height; + color_type = info_ptr->color_type; + bit_depth = info_ptr->bit_depth; + + number_of_passes = png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + + + /* read file */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[read_png_file] Error during read_image"); + + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); + for (y=0; y<height; y++) + row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes); + + png_read_image(png_ptr, row_pointers); +} + + +void write_png_file(char* file_name) +{ + /* create file */ + FILE *fp = fopen(file_name, "wb"); + if (!fp) + abort_("[write_png_file] File %s could not be opened for writing", file_name); + + + /* initialize stuff */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + abort_("[write_png_file] png_create_write_struct failed"); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + abort_("[write_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during init_io"); + + png_init_io(png_ptr, fp); + + + /* write header */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during writing header"); + + png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + + /* write bytes */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during writing bytes"); + + png_write_image(png_ptr, row_pointers); + + + /* end write */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during end of write"); + + png_write_end(png_ptr, NULL); + +} + +void process_file(char* shift) +{ + int shift_ = atoi(shift); + + if (info_ptr->color_type != PNG_COLOR_TYPE_RGBA) + abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (is %d)", info_ptr->color_type); + + width -= shift_; + for (y=0; y<height; y++) { + row_pointers[y] += 4 * shift_; + } + +} + + +int main(int argc, char **argv) +{ + if (argc != 4) + abort_("Usage: program_name <file_in> <file_out> <shift>"); + + read_png_file(argv[1]); + process_file(argv[3]); + write_png_file(argv[2]); +} diff --git a/tools/simplify-drakx-modules b/tools/simplify-drakx-modules new file mode 100755 index 000000000..ec8df1e76 --- /dev/null +++ b/tools/simplify-drakx-modules @@ -0,0 +1,5 @@ +#!/usr/bin/perl -pi + +s/^\s*use\s+(diagnostics|strict|vars|warnings).*//g; + +/^__END__/ and $_ = '', close ARGV; diff --git a/tools/specific_arch b/tools/specific_arch new file mode 100755 index 000000000..a86b7bc43 --- /dev/null +++ b/tools/specific_arch @@ -0,0 +1,9 @@ +#!/usr/bin/perl + +use MDK::Common; + +print join(' ', map { + my $arch = arch(); + $arch = $compat_arch{$arch} while $arch && !-e "$_.$arch"; + -e "$_.$arch" ? "$_.$arch" : (); + } @ARGV), "\n"; diff --git a/tools/xhost+.c b/tools/xhost+.c new file mode 100644 index 000000000..58781274e --- /dev/null +++ b/tools/xhost+.c @@ -0,0 +1,11 @@ +#include <stdlib.h> +#include <X11/Xlib.h> + + +int main(int argc, char **argv) { + Display *d = XOpenDisplay(getenv("DISPLAY") ? getenv("DISPLAY") : ":0"); + if (d == NULL) exit(1); + XDisableAccessControl(d); + XCloseDisplay(d); + exit(0); +} |