--- network-manager-applet-0.7~~svn20081005t082522.orig/intltool-extract.in +++ network-manager-applet-0.7~~svn20081005t082522/intltool-extract.in @@ -0,0 +1,875 @@ +#!@INTLTOOL_PERL@ -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +# +# The Intltool Message Extractor +# +# Copyright (C) 2000-2001, 2003 Free Software Foundation. +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Kenneth Christiansen +# Darin Adler +# + +## Release information +my $PROGRAM = "intltool-extract"; +my $PACKAGE = "intltool"; +my $VERSION = "0.37.0"; + +## Loaded modules +use strict; +use File::Basename; +use Getopt::Long; + +## Scalars used by the option stuff +my $TYPE_ARG = "0"; +my $LOCAL_ARG = "0"; +my $HELP_ARG = "0"; +my $VERSION_ARG = "0"; +my $UPDATE_ARG = "0"; +my $QUIET_ARG = "0"; +my $SRCDIR_ARG = "."; + +my $FILE; +my $OUTFILE; + +my $gettext_type = ""; +my $input; +my %messages = (); +my %loc = (); +my %count = (); +my %comments = (); +my $strcount = 0; + +my $XMLCOMMENT = ""; + +## Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +## Always print first +$| = 1; + +## Handle options +GetOptions ( + "type=s" => \$TYPE_ARG, + "local|l" => \$LOCAL_ARG, + "help|h" => \$HELP_ARG, + "version|v" => \$VERSION_ARG, + "update" => \$UPDATE_ARG, + "quiet|q" => \$QUIET_ARG, + "srcdir=s" => \$SRCDIR_ARG, + ) or &error; + +&split_on_argument; + + +## Check for options. +## This section will check for the different options. + +sub split_on_argument { + + if ($VERSION_ARG) { + &version; + + } elsif ($HELP_ARG) { + &help; + + } elsif ($LOCAL_ARG) { + &place_local; + &extract; + + } elsif ($UPDATE_ARG) { + &place_normal; + &extract; + + } elsif (@ARGV > 0) { + &place_normal; + &message; + &extract; + + } else { + &help; + + } +} + +sub place_normal { + $FILE = $ARGV[0]; + $OUTFILE = "$FILE.h"; + + my $dirname = dirname ($OUTFILE); + if (! -d "$dirname" && $dirname ne "") { + system ("mkdir -p $dirname"); + } +} + +sub place_local { + $FILE = $ARGV[0]; + $OUTFILE = fileparse($FILE, ()); + if (!-e "tmp/") { + system("mkdir tmp/"); + } + $OUTFILE = "./tmp/$OUTFILE.h" +} + +sub determine_type { + if ($TYPE_ARG =~ /^gettext\/(.*)/) { + $gettext_type=$1 + } +} + +## Sub for printing release information +sub version{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) $VERSION +Copyright (C) 2000, 2003 Free Software Foundation, Inc. +Written by Kenneth Christiansen, 2000. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +## Sub for printing usage information +sub help { + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... [FILENAME] +Generates a header file from an XML source file. + +It grabs all strings between <_translatable_node> and its end tag in +XML files. Read manpage (man ${PROGRAM}) for more info. + + --type=TYPE Specify the file type of FILENAME. Currently supports: + "gettext/glade", "gettext/ini", "gettext/keys" + "gettext/rfc822deb", "gettext/schemas", + "gettext/scheme", "gettext/xml", "gettext/quoted", + "gettext/quotedxml" + -l, --local Writes output into current working directory + (conflicts with --update) + --update Writes output into the same directory the source file + reside (conflicts with --local) + --srcdir Root of the source tree + -v, --version Output version information and exit + -h, --help Display this help and exit + -q, --quiet Quiet mode + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + +## Sub for printing error messages +sub error{ + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + +sub message { + print "Generating C format header file for translation.\n" unless $QUIET_ARG; +} + +sub extract { + &determine_type; + + &convert; + + open OUT, ">$OUTFILE"; + binmode (OUT) if $^O eq 'MSWin32'; + &msg_write; + close OUT; + + print "Wrote $OUTFILE\n" unless $QUIET_ARG; +} + +sub convert { + + ## Reading the file + { + local (*IN); + local $/; #slurp mode + open (IN, "<$SRCDIR_ARG/$FILE") || die "can't open $SRCDIR_ARG/$FILE: $!"; + $input = ; + } + + &type_ini if $gettext_type eq "ini"; + &type_keys if $gettext_type eq "keys"; + &type_xml if $gettext_type eq "xml"; + &type_glade if $gettext_type eq "glade"; + &type_scheme if $gettext_type eq "scheme"; + &type_schemas if $gettext_type eq "schemas"; + &type_rfc822deb if $gettext_type eq "rfc822deb"; + &type_quoted if $gettext_type eq "quoted"; + &type_quotedxml if $gettext_type eq "quotedxml"; +} + +sub entity_decode_minimal +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + + return $_; +} + +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/<//g; + s/&/&/g; + + return $_; +} + +sub escape_char +{ + return '\"' if $_ eq '"'; + return '\n' if $_ eq "\n"; + return '\\\\' if $_ eq '\\'; + + return $_; +} + +sub escape +{ + my ($string) = @_; + return join "", map &escape_char, split //, $string; +} + +sub type_ini { + ### For generic translatable desktop files ### + while ($input =~ /^(#(.+)\n)?^_.*=(.*)$/mg) { + if (defined($2)) { + $comments{$3} = $2; + } + $messages{$3} = []; + } +} + +sub type_keys { + ### For generic translatable mime/keys files ### + while ($input =~ /^\s*_\w+=(.*)$/mg) { + $messages{$1} = []; + } +} + +sub type_xml { + ### For generic translatable XML files ### + my $tree = readXml($input); + parseTree(0, $tree); +} + +sub print_var { + my $var = shift; + my $vartype = ref $var; + + if ($vartype =~ /ARRAY/) { + my @arr = @{$var}; + print "[ "; + foreach my $el (@arr) { + print_var($el); + print ", "; + } + print "] "; + } elsif ($vartype =~ /HASH/) { + my %hash = %{$var}; + print "{ "; + foreach my $key (keys %hash) { + print "$key => "; + print_var($hash{$key}); + print ", "; + } + print "} "; + } else { + print $var; + } +} + +# Same syntax as getAttributeString in intltool-merge.in.in, similar logic (look for ## differences comment) +sub getAttributeString +{ + my $sub = shift; + my $do_translate = shift || 1; + my $language = shift || ""; + my $translate = shift; + my $result = ""; + foreach my $e (reverse(sort(keys %{ $sub }))) { + my $key = $e; + my $string = $sub->{$e}; + my $quote = '"'; + + $string =~ s/^[\s]+//; + $string =~ s/[\s]+$//; + + if ($string =~ /^'.*'$/) + { + $quote = "'"; + } + $string =~ s/^['"]//g; + $string =~ s/['"]$//g; + + ## differences from intltool-merge.in.in + if ($key =~ /^_/) { + $comments{entity_decode($string)} = $XMLCOMMENT if $XMLCOMMENT; + $messages{entity_decode($string)} = []; + $$translate = 2; + } + ## differences end here from intltool-merge.in.in + $result .= " $key=$quote$string$quote"; + } + return $result; +} + +# Verbatim copy from intltool-merge.in.in +sub getXMLstring +{ + my $ref = shift; + my $spacepreserve = shift || 0; + my @list = @{ $ref }; + my $result = ""; + + my $count = scalar(@list); + my $attrs = $list[0]; + my $index = 1; + + $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); + $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/)); + + while ($index < $count) { + my $type = $list[$index]; + my $content = $list[$index+1]; + if (! $type ) { + # We've got CDATA + if ($content) { + # lets strip the whitespace here, and *ONLY* here + $content =~ s/\s+/ /gs if (!$spacepreserve); + $result .= $content; + } + } elsif ( "$type" ne "1" ) { + # We've got another element + $result .= "<$type"; + $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements + if ($content) { + my $subresult = getXMLstring($content, $spacepreserve); + if ($subresult) { + $result .= ">".$subresult . ""; + } else { + $result .= "/>"; + } + } else { + $result .= "/>"; + } + } + $index += 2; + } + return $result; +} + +# Verbatim copy from intltool-merge.in.in, except for MULTIPLE_OUTPUT handling removed +# Translate list of nodes if necessary +sub translate_subnodes +{ + my $fh = shift; + my $content = shift; + my $language = shift || ""; + my $singlelang = shift || 0; + my $spacepreserve = shift || 0; + + my @nodes = @{ $content }; + + my $count = scalar(@nodes); + my $index = 0; + while ($index < $count) { + my $type = $nodes[$index]; + my $rest = $nodes[$index+1]; + traverse($fh, $type, $rest, $language, $spacepreserve); + $index += 2; + } +} + +# Based on traverse() in intltool-merge.in.in +sub traverse +{ + my $fh = shift; # unused, to allow us to sync code between -merge and -extract + my $nodename = shift; + my $content = shift; + my $language = shift || ""; + my $spacepreserve = shift || 0; + + if ($nodename && "$nodename" eq "1") { + $XMLCOMMENT = $content; + } elsif ($nodename) { + # element + my @all = @{ $content }; + my $attrs = shift @all; + my $translate = 0; + my $outattr = getAttributeString($attrs, 1, $language, \$translate); + + if ($nodename =~ /^_/) { + $translate = 1; + $nodename =~ s/^_//; + } + my $lookup = ''; + + $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/)); + $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); + + if ($translate) { + $lookup = getXMLstring($content, $spacepreserve); + if (!$spacepreserve) { + $lookup =~ s/^\s+//s; + $lookup =~ s/\s+$//s; + } + + if ($lookup && $translate != 2) { + $comments{$lookup} = $XMLCOMMENT if $XMLCOMMENT; + $messages{$lookup} = []; + } elsif ($translate == 2) { + translate_subnodes($fh, \@all, $language, 1, $spacepreserve); + } + } else { + $XMLCOMMENT = ""; + my $count = scalar(@all); + if ($count > 0) { + my $index = 0; + while ($index < $count) { + my $type = $all[$index]; + my $rest = $all[$index+1]; + traverse($fh, $type, $rest, $language, $spacepreserve); + $index += 2; + } + } + } + $XMLCOMMENT = ""; + } +} + + +# Verbatim copy from intltool-merge.in.in, $fh for compatibility +sub parseTree +{ + my $fh = shift; + my $ref = shift; + my $language = shift || ""; + + my $name = shift @{ $ref }; + my $cont = shift @{ $ref }; + + while (!$name || "$name" eq "1") { + $name = shift @{ $ref }; + $cont = shift @{ $ref }; + } + + my $spacepreserve = 0; + my $attrs = @{$cont}[0]; + $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); + + traverse($fh, $name, $cont, $language, $spacepreserve); +} + +# Verbatim copy from intltool-merge.in.in +sub intltool_tree_comment +{ + my $expat = shift; + my $data = $expat->original_string(); + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + $data =~ s/^$//s; + push @$clist, 1 => $data; +} + +# Verbatim copy from intltool-merge.in.in +sub intltool_tree_cdatastart +{ + my $expat = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + push @$clist, 0 => $expat->original_string(); +} + +# Verbatim copy from intltool-merge.in.in +sub intltool_tree_cdataend +{ + my $expat = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + $clist->[$pos] .= $expat->original_string(); +} + +# Verbatim copy from intltool-merge.in.in +sub intltool_tree_char +{ + my $expat = shift; + my $text = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + # Use original_string so that we retain escaped entities + # in CDATA sections. + # + if ($pos > 0 and $clist->[$pos - 1] eq '0') { + $clist->[$pos] .= $expat->original_string(); + } else { + push @$clist, 0 => $expat->original_string(); + } +} + +# Verbatim copy from intltool-merge.in.in +sub intltool_tree_start +{ + my $expat = shift; + my $tag = shift; + my @origlist = (); + + # Use original_string so that we retain escaped entities + # in attribute values. We must convert the string to an + # @origlist array to conform to the structure of the Tree + # Style. + # + my @original_array = split /\x/, $expat->original_string(); + my $source = $expat->original_string(); + + # Remove leading tag. + # + $source =~ s|^\s*<\s*(\S+)||s; + + # Grab attribute key/value pairs and push onto @origlist array. + # + while ($source) + { + if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/) + { + $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s; + push @origlist, $1; + push @origlist, '"' . $2 . '"'; + } + elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/) + { + $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s; + push @origlist, $1; + push @origlist, "'" . $2 . "'"; + } + else + { + last; + } + } + + my $ol = [ { @origlist } ]; + + push @{ $expat->{Lists} }, $expat->{Curlist}; + push @{ $expat->{Curlist} }, $tag => $ol; + $expat->{Curlist} = $ol; +} + +# Copied from intltool-merge.in.in and added comment handler. +sub readXml +{ + my $xmldoc = shift || return; + my $ret = eval 'require XML::Parser'; + if(!$ret) { + die "You must have XML::Parser installed to run $0\n\n"; + } + my $xp = new XML::Parser(Style => 'Tree'); + $xp->setHandlers(Char => \&intltool_tree_char); + $xp->setHandlers(Start => \&intltool_tree_start); + $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart); + $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend); + + ## differences from intltool-merge.in.in + $xp->setHandlers(Comment => \&intltool_tree_comment); + ## differences end here from intltool-merge.in.in + + my $tree = $xp->parse($xmldoc); + #print_var($tree); + +# Hello thereHowdydo +# would be: +# [foo, [{}, 1, "comment", head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar, +# [{}, 0, "Howdy", ref, [{}]], 0, "do" ] ] + + return $tree; +} + +sub type_schemas { + ### For schemas XML files ### + + # FIXME: We should handle escaped < (less than) + while ($input =~ / + \s* + (\s*(?:\s*)?(.*?)\s*<\/default>\s*)? + (\s*(?:\s*)?(.*?)\s*<\/short>\s*)? + (\s*(?:\s*)?(.*?)\s*<\/long>\s*)? + <\/locale> + /sgx) { + my @totranslate = ($3,$6,$9); + my @eachcomment = ($2,$5,$8); + foreach (@totranslate) { + my $currentcomment = shift @eachcomment; + next if !$_; + s/\s+/ /g; + $messages{entity_decode_minimal($_)} = []; + $comments{entity_decode_minimal($_)} = $currentcomment if (defined($currentcomment)); + } + } +} + +sub type_rfc822deb { + ### For rfc822-style Debian configuration files ### + + my $lineno = 1; + my $type = ''; + while ($input =~ /\G(.*?)(^|\n)(_+)([^:]+):[ \t]*(.*?)(?=\n\S|$)/sg) + { + my ($pre, $newline, $underscore, $tag, $text) = ($1, $2, $3, $4, $5); + while ($pre =~ m/\n/g) + { + $lineno ++; + } + $lineno += length($newline); + my @str_list = rfc822deb_split(length($underscore), $text); + for my $str (@str_list) + { + $strcount++; + $messages{$str} = []; + $loc{$str} = $lineno; + $count{$str} = $strcount; + my $usercomment = ''; + while($pre =~ s/(^|\n)#([^\n]*)$//s) + { + $usercomment = "\n" . $2 . $usercomment; + } + $comments{$str} = $tag . $usercomment; + } + $lineno += ($text =~ s/\n//g); + } +} + +sub rfc822deb_split { + # Debian defines a special way to deal with rfc822-style files: + # when a value contain newlines, it consists of + # 1. a short form (first line) + # 2. a long description, all lines begin with a space, + # and paragraphs are separated by a single dot on a line + # This routine returns an array of all paragraphs, and reformat + # them. + # When first argument is 2, the string is a comma separated list of + # values. + my $type = shift; + my $text = shift; + $text =~ s/^[ \t]//mg; + return (split(/, */, $text, 0)) if $type ne 1; + return ($text) if $text !~ /\n/; + + $text =~ s/([^\n]*)\n//; + my @list = ($1); + my $str = ''; + for my $line (split (/\n/, $text)) + { + chomp $line; + if ($line =~ /^\.\s*$/) + { + # New paragraph + $str =~ s/\s*$//; + push(@list, $str); + $str = ''; + } + elsif ($line =~ /^\s/) + { + # Line which must not be reformatted + $str .= "\n" if length ($str) && $str !~ /\n$/; + $line =~ s/\s+$//; + $str .= $line."\n"; + } + else + { + # Continuation line, remove newline + $str .= " " if length ($str) && $str !~ /\n$/; + $str .= $line; + } + } + $str =~ s/\s*$//; + push(@list, $str) if length ($str); + return @list; +} + +sub type_quoted { + while ($input =~ /\"(([^\"]|\\\")*[^\\\"])\"/g) { + my $message = $1; + my $before = $`; + $message =~ s/\\\"/\"/g; + $before =~ s/[^\n]//g; + $messages{$message} = []; + $loc{$message} = length ($before) + 2; + } +} + +sub type_quotedxml { + while ($input =~ /\"(([^\"]|\\\")*[^\\\"])\"/g) { + my $message = $1; + my $before = $`; + $message =~ s/\\\"/\"/g; + $message = entity_decode($message); + $before =~ s/[^\n]//g; + $messages{$message} = []; + $loc{$message} = length ($before) + 2; + } +} + +sub type_glade { + ### For translatable Glade XML files ### + + my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message"; + + while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) { + # Glade sometimes uses tags that normally mark translatable things for + # little bits of non-translatable content. We work around this by not + # translating strings that only includes something like label4 or window1. + $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label|dialog)[0-9]+$/; + } + + while ($input =~ /(..[^<]*)<\/items>/sg) { + for my $item (split (/\n/, $1)) { + $messages{entity_decode($item)} = []; + } + } + + ## handle new glade files + while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"(?:\s+[^>]*comments\s*=\s*"([^"]*)")?[^>]*>([^<]+)<\/\1>/sg) { + $messages{entity_decode($3)} = [] unless $3 =~ /^(window|label)[0-9]+$/; + if (defined($2) and !($3 =~ /^(window|label)[0-9]+$/)) { + $comments{entity_decode($3)} = entity_decode($2) ; + } + } + while ($input =~ /]*)"\s+description="([^>]+)"\/>/sg) { + $messages{entity_decode_minimal($2)} = []; + } +} + +sub type_scheme { + my ($line, $i, $state, $str, $trcomment, $char); + for $line (split(/\n/, $input)) { + $i = 0; + $state = 0; # 0 - nothing, 1 - string, 2 - translatable string + while ($i < length($line)) { + if (substr($line,$i,1) eq "\"") { + if ($state == 2) { + $comments{$str} = $trcomment if ($trcomment); + $messages{$str} = []; + $str = ''; + $state = 0; $trcomment = ""; + } elsif ($state == 1) { + $str = ''; + $state = 0; $trcomment = ""; + } else { + $state = 1; + $str = ''; + if ($i>0 && substr($line,$i-1,1) eq '_') { + $state = 2; + } + } + } elsif (!$state) { + if (substr($line,$i,1) eq ";") { + $trcomment = substr($line,$i+1); + $trcomment =~ s/^;*\s*//; + $i = length($line); + } elsif ($trcomment && substr($line,$i,1) !~ /\s|\(|\)|_/) { + $trcomment = ""; + } + } else { + if (substr($line,$i,1) eq "\\") { + $char = substr($line,$i+1,1); + if ($char ne "\"" && $char ne "\\") { + $str = $str . "\\"; + } + $i++; + } + $str = $str . substr($line,$i,1); + } + $i++; + } + } +} + +sub msg_write { + my @msgids; + if (%count) + { + @msgids = sort { $count{$a} <=> $count{$b} } keys %count; + } + else + { + @msgids = sort keys %messages; + } + for my $message (@msgids) + { + my $offsetlines = 1; + $offsetlines++ if $message =~ /%/; + if (defined ($comments{$message})) + { + while ($comments{$message} =~ m/\n/g) + { + $offsetlines++; + } + } + print OUT "# ".($loc{$message} - $offsetlines). " \"$FILE\"\n" + if defined $loc{$message}; + print OUT "/* ".$comments{$message}." */\n" + if defined $comments{$message}; + print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/; + + my @lines = split (/\n/, $message, -1); + for (my $n = 0; $n < @lines; $n++) + { + if ($n == 0) + { + print OUT "char *s = N_(\""; + } + else + { + print OUT " \""; + } + + print OUT escape($lines[$n]); + + if ($n < @lines - 1) + { + print OUT "\\n\"\n"; + } + else + { + print OUT "\");\n"; + } + } + } +} + --- network-manager-applet-0.7~~svn20081005t082522.orig/intltool-merge.in +++ network-manager-applet-0.7~~svn20081005t082522/intltool-merge.in @@ -0,0 +1,1506 @@ +#!@INTLTOOL_PERL@ -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +# +# The Intltool Message Merger +# +# Copyright (C) 2000, 2003 Free Software Foundation. +# Copyright (C) 2000, 2001 Eazel, Inc +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Maciej Stachowiak +# Kenneth Christiansen +# Darin Adler +# +# Proper XML UTF-8'ification written by Cyrille Chepelov +# + +## Release information +my $PROGRAM = "intltool-merge"; +my $PACKAGE = "intltool"; +my $VERSION = "0.37.0"; + +## Loaded modules +use strict; +use Getopt::Long; +use Text::Wrap; +use File::Basename; + +my $must_end_tag = -1; +my $last_depth = -1; +my $translation_depth = -1; +my @tag_stack = (); +my @entered_tag = (); +my @translation_strings = (); +my $leading_space = ""; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $BA_STYLE_ARG = 0; +my $XML_STYLE_ARG = 0; +my $KEYS_STYLE_ARG = 0; +my $DESKTOP_STYLE_ARG = 0; +my $SCHEMAS_STYLE_ARG = 0; +my $RFC822DEB_STYLE_ARG = 0; +my $QUOTED_STYLE_ARG = 0; +my $QUOTEDXML_STYLE_ARG = 0; +my $QUIET_ARG = 0; +my $PASS_THROUGH_ARG = 0; +my $UTF8_ARG = 0; +my $MULTIPLE_OUTPUT = 0; +my $cache_file; + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "quiet|q" => \$QUIET_ARG, + "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility + "ba-style|b" => \$BA_STYLE_ARG, + "xml-style|x" => \$XML_STYLE_ARG, + "keys-style|k" => \$KEYS_STYLE_ARG, + "desktop-style|d" => \$DESKTOP_STYLE_ARG, + "schemas-style|s" => \$SCHEMAS_STYLE_ARG, + "rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG, + "quoted-style" => \$QUOTED_STYLE_ARG, + "quotedxml-style" => \$QUOTEDXML_STYLE_ARG, + "pass-through|p" => \$PASS_THROUGH_ARG, + "utf8|u" => \$UTF8_ARG, + "multiple-output|m" => \$MULTIPLE_OUTPUT, + "cache|c=s" => \$cache_file + ) or &error; + +my $PO_DIR; +my $FILE; +my $OUTFILE; + +my %po_files_by_lang = (); +my %translations = (); +my $iconv = $ENV{"ICONV"} || "iconv"; +my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null'); + +sub isProgramInPath +{ + my ($file) = @_; + # If either a file exists, or when run it returns 0 exit status + return 1 if ((-x $file) or (system("$file -l >$devnull") == 0)); + return 0; +} + +if (! isProgramInPath ("$iconv")) +{ + print STDERR " *** iconv is not found on this system!\n". + " *** Without it, intltool-merge can not convert encodings.\n"; + exit; +} + +# Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +# XML quoted string contents +my $q = "[^\\\"]*"; + +## Check for options. + +if ($VERSION_ARG) +{ + &print_version; +} +elsif ($HELP_ARG) +{ + &print_help; +} +elsif ($BA_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &ba_merge_translations; + &finalize; +} +elsif ($XML_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &xml_merge_output; + &finalize; +} +elsif ($KEYS_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &keys_merge_translations; + &finalize; +} +elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &desktop_merge_translations; + &finalize; +} +elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &schemas_merge_translations; + &finalize; +} +elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &rfc822deb_merge_translations; + &finalize; +} +elsif (($QUOTED_STYLE_ARG || $QUOTEDXML_STYLE_ARG) && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + "ed_merge_translations($QUOTEDXML_STYLE_ARG); + &finalize; +} +else +{ + &print_help; +} + +exit; + +## Sub for printing release information +sub print_version +{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) ${VERSION} +Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen. + +Copyright (C) 2000-2003 Free Software Foundation, Inc. +Copyright (C) 2000-2001 Eazel, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +## Sub for printing usage information +sub print_help +{ + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE +Generates an output file that includes some localized attributes from an +untranslated source file. + +Mandatory options: (exactly one must be specified) + -b, --ba-style includes translations in the bonobo-activation style + -d, --desktop-style includes translations in the desktop style + -k, --keys-style includes translations in the keys style + -s, --schemas-style includes translations in the schemas style + -r, --rfc822deb-style includes translations in the RFC822 style + --quoted-style includes translations in the quoted string style + --quotedxml-style includes translations in the quoted xml string style + -x, --xml-style includes translations in the standard xml style + +Other options: + -u, --utf8 convert all strings to UTF-8 before merging + (default for everything except RFC822 style) + -p, --pass-through deprecated, does nothing and issues a warning + -m, --multiple-output output one localized file per locale, instead of + a single file containing all localized elements + -c, --cache=FILE specify cache file name + (usually \$top_builddir/po/.intltool-merge-cache) + -q, --quiet suppress most messages + --help display this help and exit + --version output version information and exit + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + + +## Sub for printing error messages +sub print_error +{ + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + + +sub print_message +{ + print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG; +} + + +sub preparation +{ + $PO_DIR = $ARGV[0]; + $FILE = $ARGV[1]; + $OUTFILE = $ARGV[2]; + + &gather_po_files; + &get_translation_database; +} + +# General-purpose code for looking up translations in .po files + +sub po_file2lang +{ + my ($tmp) = @_; + $tmp =~ s/^.*\/(.*)\.po$/$1/; + return $tmp; +} + +sub gather_po_files +{ + if (my $linguas = $ENV{"LINGUAS"}) + { + for my $lang (split / /, $linguas) { + my $po_file = $PO_DIR . "/" . $lang . ".po"; + if (-e $po_file) { + $po_files_by_lang{$lang} = $po_file; + } + } + } + else + { + if (open LINGUAS_FILE, "$PO_DIR/LINGUAS") + { + while () + { + next if /^#/; + + for my $lang (split) + { + chomp ($lang); + my $po_file = $PO_DIR . "/" . $lang . ".po"; + if (-e $po_file) { + $po_files_by_lang{$lang} = $po_file; + } + } + } + + close LINGUAS_FILE; + } + else + { + for my $po_file (glob "$PO_DIR/*.po") { + $po_files_by_lang{po_file2lang($po_file)} = $po_file; + } + } + } +} + +sub get_local_charset +{ + my ($encoding) = @_; + my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "@INTLTOOL_LIBDIR@/charset.alias"; + + # seek character encoding aliases in charset.alias (glib) + + if (open CHARSET_ALIAS, $alias_file) + { + while () + { + next if /^\#/; + return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i) + } + + close CHARSET_ALIAS; + } + + # if not found, return input string + + return $encoding; +} + +sub get_po_encoding +{ + my ($in_po_file) = @_; + my $encoding = ""; + + open IN_PO_FILE, $in_po_file or die; + while () + { + ## example: "Content-Type: text/plain; charset=ISO-8859-1\n" + if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/) + { + $encoding = $1; + last; + } + } + close IN_PO_FILE; + + if (!$encoding) + { + print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG; + $encoding = "ISO-8859-1"; + } + + system ("$iconv -f $encoding -t UTF-8 <$devnull 2>$devnull"); + if ($?) { + $encoding = get_local_charset($encoding); + } + + return $encoding +} + +sub utf8_sanity_check +{ + print STDERR "Warning: option --pass-through has been removed.\n" if $PASS_THROUGH_ARG; + $UTF8_ARG = 1; +} + +sub get_translation_database +{ + if ($cache_file) { + &get_cached_translation_database; + } else { + &create_translation_database; + } +} + +sub get_newest_po_age +{ + my $newest_age; + + foreach my $file (values %po_files_by_lang) + { + my $file_age = -M $file; + $newest_age = $file_age if !$newest_age || $file_age < $newest_age; + } + + $newest_age = 0 if !$newest_age; + + return $newest_age; +} + +sub create_cache +{ + print "Generating and caching the translation database\n" unless $QUIET_ARG; + + &create_translation_database; + + open CACHE, ">$cache_file" || die; + print CACHE join "\x01", %translations; + close CACHE; +} + +sub load_cache +{ + print "Found cached translation database\n" unless $QUIET_ARG; + + my $contents; + open CACHE, "<$cache_file" || die; + { + local $/; + $contents = ; + } + close CACHE; + %translations = split "\x01", $contents; +} + +sub get_cached_translation_database +{ + my $cache_file_age = -M $cache_file; + if (defined $cache_file_age) + { + if ($cache_file_age <= &get_newest_po_age) + { + &load_cache; + return; + } + print "Found too-old cached translation database\n" unless $QUIET_ARG; + } + + &create_cache; +} + +sub create_translation_database +{ + for my $lang (keys %po_files_by_lang) + { + my $po_file = $po_files_by_lang{$lang}; + + if ($UTF8_ARG) + { + my $encoding = get_po_encoding ($po_file); + + if (lc $encoding eq "utf-8") + { + open PO_FILE, "<$po_file"; + } + else + { + print "NOTICE: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;; + + open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|"; + } + } + else + { + open PO_FILE, "<$po_file"; + } + + my $nextfuzzy = 0; + my $inmsgid = 0; + my $inmsgstr = 0; + my $msgid = ""; + my $msgstr = ""; + + while () + { + $nextfuzzy = 1 if /^#, fuzzy/; + + if (/^msgid "((\\.|[^\\]+)*)"/ ) + { + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + $msgid = ""; + $msgstr = ""; + + if ($nextfuzzy) { + $inmsgid = 0; + } else { + $msgid = unescape_po_string($1); + $inmsgid = 1; + } + $inmsgstr = 0; + $nextfuzzy = 0; + } + + if (/^msgstr "((\\.|[^\\]+)*)"/) + { + $msgstr = unescape_po_string($1); + $inmsgstr = 1; + $inmsgid = 0; + } + + if (/^"((\\.|[^\\]+)*)"/) + { + $msgid .= unescape_po_string($1) if $inmsgid; + $msgstr .= unescape_po_string($1) if $inmsgstr; + } + } + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + } +} + +sub finalize +{ +} + +sub unescape_one_sequence +{ + my ($sequence) = @_; + + return "\\" if $sequence eq "\\\\"; + return "\"" if $sequence eq "\\\""; + return "\n" if $sequence eq "\\n"; + return "\r" if $sequence eq "\\r"; + return "\t" if $sequence eq "\\t"; + return "\b" if $sequence eq "\\b"; + return "\f" if $sequence eq "\\f"; + return "\a" if $sequence eq "\\a"; + return chr(11) if $sequence eq "\\v"; # vertical tab, see ascii(7) + + return chr(hex($1)) if ($sequence =~ /\\x([0-9a-fA-F]{2})/); + return chr(oct($1)) if ($sequence =~ /\\([0-7]{3})/); + + # FIXME: Is \0 supported as well? Kenneth and Rodney don't want it, see bug #48489 + + return $sequence; +} + +sub unescape_po_string +{ + my ($string) = @_; + + $string =~ s/(\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\.)/unescape_one_sequence($1)/eg; + + return $string; +} + +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/<//g; + s/&/&/g; + + return $_; +} + +# entity_encode: (string) +# +# Encode the given string to XML format (encode '<' etc). + +sub entity_encode +{ + my ($pre_encoded) = @_; + + my @list_of_chars = unpack ('C*', $pre_encoded); + + # with UTF-8 we only encode minimalistic + return join ('', map (&entity_encode_int_minimalist, @list_of_chars)); +} + +sub entity_encode_int_minimalist +{ + return """ if $_ == 34; + return "&" if $_ == 38; + return "'" if $_ == 39; + return "<" if $_ == 60; + return ">" if $_ == 62; + return chr $_; +} + +sub entity_encoded_translation +{ + my ($lang, $string) = @_; + + my $translation = $translations{$lang, $string}; + return $string if !$translation; + return entity_encode ($translation); +} + +## XML (bonobo-activation specific) merge code + +sub ba_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!"; + # Binmode so that selftest works ok if using a native Win32 Perl... + binmode (OUTPUT) if $^O eq 'MSWin32'; + + while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) + { + print OUTPUT $1; + + my $node = $2 . "\n"; + + my @strings = (); + $_ = $node; + while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) { + push @strings, entity_decode($3); + } + print OUTPUT; + + my %langs; + for my $string (@strings) + { + for my $lang (keys %po_files_by_lang) + { + $langs{$lang} = 1 if $translations{$lang, $string}; + } + } + + for my $lang (sort keys %langs) + { + $_ = $node; + s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s; + s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg; + print OUTPUT; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + + +## XML (non-bonobo-activation) merge code + + +# Process tag attributes +# Only parameter is a HASH containing attributes -> values mapping +sub getAttributeString +{ + my $sub = shift; + my $do_translate = shift || 0; + my $language = shift || ""; + my $result = ""; + my $translate = shift; + foreach my $e (reverse(sort(keys %{ $sub }))) { + my $key = $e; + my $string = $sub->{$e}; + my $quote = '"'; + + $string =~ s/^[\s]+//; + $string =~ s/[\s]+$//; + + if ($string =~ /^'.*'$/) + { + $quote = "'"; + } + $string =~ s/^['"]//g; + $string =~ s/['"]$//g; + + if ($do_translate && $key =~ /^_/) { + $key =~ s|^_||g; + if ($language) { + # Handle translation + my $decode_string = entity_decode($string); + my $translation = $translations{$language, $decode_string}; + if ($translation) { + $translation = entity_encode($translation); + $string = $translation; + } + $$translate = 2; + } else { + $$translate = 2 if ($translate && (!$$translate)); # watch not to "overwrite" $translate + } + } + + $result .= " $key=$quote$string$quote"; + } + return $result; +} + +# Returns a translatable string from XML node, it works on contents of every node in XML::Parser tree +sub getXMLstring +{ + my $ref = shift; + my $spacepreserve = shift || 0; + my @list = @{ $ref }; + my $result = ""; + + my $count = scalar(@list); + my $attrs = $list[0]; + my $index = 1; + + $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); + $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/)); + + while ($index < $count) { + my $type = $list[$index]; + my $content = $list[$index+1]; + if (! $type ) { + # We've got CDATA + if ($content) { + # lets strip the whitespace here, and *ONLY* here + $content =~ s/\s+/ /gs if (!$spacepreserve); + $result .= $content; + } + } elsif ( "$type" ne "1" ) { + # We've got another element + $result .= "<$type"; + $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements + if ($content) { + my $subresult = getXMLstring($content, $spacepreserve); + if ($subresult) { + $result .= ">".$subresult . ""; + } else { + $result .= "/>"; + } + } else { + $result .= "/>"; + } + } + $index += 2; + } + return $result; +} + +# Translate list of nodes if necessary +sub translate_subnodes +{ + my $fh = shift; + my $content = shift; + my $language = shift || ""; + my $singlelang = shift || 0; + my $spacepreserve = shift || 0; + + my @nodes = @{ $content }; + + my $count = scalar(@nodes); + my $index = 0; + while ($index < $count) { + my $type = $nodes[$index]; + my $rest = $nodes[$index+1]; + if ($singlelang) { + my $oldMO = $MULTIPLE_OUTPUT; + $MULTIPLE_OUTPUT = 1; + traverse($fh, $type, $rest, $language, $spacepreserve); + $MULTIPLE_OUTPUT = $oldMO; + } else { + traverse($fh, $type, $rest, $language, $spacepreserve); + } + $index += 2; + } +} + +sub isWellFormedXmlFragment +{ + my $ret = eval 'require XML::Parser'; + if(!$ret) { + die "You must have XML::Parser installed to run $0\n\n"; + } + + my $fragment = shift; + return 0 if (!$fragment); + + $fragment = "$fragment"; + my $xp = new XML::Parser(Style => 'Tree'); + my $tree = 0; + eval { $tree = $xp->parse($fragment); }; + return $tree; +} + +sub traverse +{ + my $fh = shift; + my $nodename = shift; + my $content = shift; + my $language = shift || ""; + my $spacepreserve = shift || 0; + + if (!$nodename) { + if ($content =~ /^[\s]*$/) { + $leading_space .= $content; + } + print $fh $content; + } else { + # element + my @all = @{ $content }; + my $attrs = shift @all; + my $translate = 0; + my $outattr = getAttributeString($attrs, 1, $language, \$translate); + + if ($nodename =~ /^_/) { + $translate = 1; + $nodename =~ s/^_//; + } + my $lookup = ''; + + $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/)); + $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); + + print $fh "<$nodename", $outattr; + if ($translate) { + $lookup = getXMLstring($content, $spacepreserve); + if (!$spacepreserve) { + $lookup =~ s/^\s+//s; + $lookup =~ s/\s+$//s; + } + + if ($lookup || $translate == 2) { + my $translation = $translations{$language, $lookup} if isWellFormedXmlFragment($translations{$language, $lookup}); + if ($MULTIPLE_OUTPUT && ($translation || $translate == 2)) { + $translation = $lookup if (!$translation); + print $fh " xml:lang=\"", $language, "\"" if $language; + print $fh ">"; + if ($translate == 2) { + translate_subnodes($fh, \@all, $language, 1, $spacepreserve); + } else { + print $fh $translation; + } + print $fh ""; + + return; # this means there will be no same translation with xml:lang="$language"... + # if we want them both, just remove this "return" + } else { + print $fh ">"; + if ($translate == 2) { + translate_subnodes($fh, \@all, $language, 1, $spacepreserve); + } else { + print $fh $lookup; + } + print $fh ""; + } + } else { + print $fh "/>"; + } + + for my $lang (sort keys %po_files_by_lang) { + if ($MULTIPLE_OUTPUT && $lang ne "$language") { + next; + } + if ($lang) { + # Handle translation + # + my $translate = 0; + my $localattrs = getAttributeString($attrs, 1, $lang, \$translate); + my $translation = $translations{$lang, $lookup} if isWellFormedXmlFragment($translations{$lang, $lookup}); + if ($translate && !$translation) { + $translation = $lookup; + } + + if ($translation || $translate) { + print $fh "\n"; + $leading_space =~ s/.*\n//g; + print $fh $leading_space; + print $fh "<", $nodename, " xml:lang=\"", $lang, "\"", $localattrs, ">"; + if ($translate == 2) { + translate_subnodes($fh, \@all, $lang, 1, $spacepreserve); + } else { + print $fh $translation; + } + print $fh ""; + } + } + } + + } else { + my $count = scalar(@all); + if ($count > 0) { + print $fh ">"; + my $index = 0; + while ($index < $count) { + my $type = $all[$index]; + my $rest = $all[$index+1]; + traverse($fh, $type, $rest, $language, $spacepreserve); + $index += 2; + } + print $fh ""; + } else { + print $fh "/>"; + } + } + } +} + +sub intltool_tree_comment +{ + my $expat = shift; + my $data = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + push @$clist, 1 => $data; +} + +sub intltool_tree_cdatastart +{ + my $expat = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + push @$clist, 0 => $expat->original_string(); +} + +sub intltool_tree_cdataend +{ + my $expat = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + $clist->[$pos] .= $expat->original_string(); +} + +sub intltool_tree_char +{ + my $expat = shift; + my $text = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + # Use original_string so that we retain escaped entities + # in CDATA sections. + # + if ($pos > 0 and $clist->[$pos - 1] eq '0') { + $clist->[$pos] .= $expat->original_string(); + } else { + push @$clist, 0 => $expat->original_string(); + } +} + +sub intltool_tree_start +{ + my $expat = shift; + my $tag = shift; + my @origlist = (); + + # Use original_string so that we retain escaped entities + # in attribute values. We must convert the string to an + # @origlist array to conform to the structure of the Tree + # Style. + # + my @original_array = split /\x/, $expat->original_string(); + my $source = $expat->original_string(); + + # Remove leading tag. + # + $source =~ s|^\s*<\s*(\S+)||s; + + # Grab attribute key/value pairs and push onto @origlist array. + # + while ($source) + { + if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/) + { + $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s; + push @origlist, $1; + push @origlist, '"' . $2 . '"'; + } + elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/) + { + $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s; + push @origlist, $1; + push @origlist, "'" . $2 . "'"; + } + else + { + last; + } + } + + my $ol = [ { @origlist } ]; + + push @{ $expat->{Lists} }, $expat->{Curlist}; + push @{ $expat->{Curlist} }, $tag => $ol; + $expat->{Curlist} = $ol; +} + +sub readXml +{ + my $filename = shift || return; + if(!-f $filename) { + die "ERROR Cannot find filename: $filename\n"; + } + + my $ret = eval 'require XML::Parser'; + if(!$ret) { + die "You must have XML::Parser installed to run $0\n\n"; + } + my $xp = new XML::Parser(Style => 'Tree'); + $xp->setHandlers(Char => \&intltool_tree_char); + $xp->setHandlers(Start => \&intltool_tree_start); + $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart); + $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend); + my $tree = $xp->parsefile($filename); + +# Hello thereHowdydo +# would be: +# [foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar, [{}, +# 0, "Howdy", ref, [{}]], 0, "do" ] ] + + return $tree; +} + +sub print_header +{ + my $infile = shift; + my $fh = shift; + my $source; + + if(!-f $infile) { + die "ERROR Cannot find filename: $infile\n"; + } + + print $fh qq{\n}; + { + local $/; + open DOCINPUT, "<${FILE}" or die; + $source = ; + close DOCINPUT; + } + if ($source =~ /()/s) + { + print $fh "$1\n"; + } + elsif ($source =~ /(]*>)/s) + { + print $fh "$1\n"; + } +} + +sub parseTree +{ + my $fh = shift; + my $ref = shift; + my $language = shift || ""; + + my $name = shift @{ $ref }; + my $cont = shift @{ $ref }; + + while (!$name || "$name" eq "1") { + $name = shift @{ $ref }; + $cont = shift @{ $ref }; + } + + my $spacepreserve = 0; + my $attrs = @{$cont}[0]; + $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); + + traverse($fh, $name, $cont, $language, $spacepreserve); +} + +sub xml_merge_output +{ + my $source; + + if ($MULTIPLE_OUTPUT) { + for my $lang (sort keys %po_files_by_lang) { + if ( ! -d $lang ) { + mkdir $lang or -d $lang or die "Cannot create subdirectory $lang: $!\n"; + } + open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n"; + binmode (OUTPUT) if $^O eq 'MSWin32'; + my $tree = readXml($FILE); + print_header($FILE, \*OUTPUT); + parseTree(\*OUTPUT, $tree, $lang); + close OUTPUT; + print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG; + } + if ( ! -d "C" ) { + mkdir "C" or -d "C" or die "Cannot create subdirectory C: $!\n"; + } + open OUTPUT, ">C/$OUTFILE" or die "Cannot open C/$OUTFILE: $!\n"; + binmode (OUTPUT) if $^O eq 'MSWin32'; + my $tree = readXml($FILE); + print_header($FILE, \*OUTPUT); + parseTree(\*OUTPUT, $tree); + close OUTPUT; + print "CREATED C/$OUTFILE\n" unless $QUIET_ARG; + } else { + open OUTPUT, ">$OUTFILE" or die "Cannot open $OUTFILE: $!\n"; + binmode (OUTPUT) if $^O eq 'MSWin32'; + my $tree = readXml($FILE); + print_header($FILE, \*OUTPUT); + parseTree(\*OUTPUT, $tree); + close OUTPUT; + print "CREATED $OUTFILE\n" unless $QUIET_ARG; + } +} + +sub keys_merge_translation +{ + my ($lang) = @_; + + if ( ! -d $lang && $MULTIPLE_OUTPUT) + { + mkdir $lang or -d $lang or die "Cannot create subdirectory $lang: $!\n"; + } + + open INPUT, "<${FILE}" or die "Cannot open ${FILE}: $!\n"; + open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n"; + binmode (OUTPUT) if $^O eq 'MSWin32'; + + while () + { + if (s/^(\s*)_(\w+=(.*))/$1$2/) + { + my $string = $3; + + if (!$MULTIPLE_OUTPUT) + { + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/[$lang]$1=$translation/; + print OUTPUT; + } + } + else + { + my $non_translated_line = $_; + my $translation = $translations{$lang, $string}; + $translation = $string if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/$1=$translation/; + print OUTPUT; + } + } + else + { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; + + print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG; +} + +sub keys_merge_translations +{ + if ($MULTIPLE_OUTPUT) + { + for my $lang (sort keys %po_files_by_lang) + { + keys_merge_translation ($lang); + } + keys_merge_translation ("C"); + } + else + { + keys_merge_translation ("."); + } +} + +sub desktop_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + binmode (OUTPUT) if $^O eq 'MSWin32'; + + while () + { + if (s/^(\s*)_(\w+=(.*))/$1$2/) + { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/${1}[$lang]=$translation/; + print OUTPUT; + } + } + else + { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub schemas_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die; + binmode (OUTPUT) if $^O eq 'MSWin32'; + + # FIXME: support attribute translations + + # Empty nodes never need translation, so unmark all of them. + # For example, <_foo/> is just replaced by . + $source =~ s|<\s*_($w+)\s*/>|<$1/>|g; + + while ($source =~ s/ + (.*?) + (\s+)((\s*) + (\s*(?:\s*)?(.*?)\s*<\/default>)?(\s*) + (\s*(?:\s*)?(.*?)\s*<\/short>)?(\s*) + (\s*(?:\s*)?(.*?)\s*<\/long>)?(\s*) + <\/locale>) + //sx) + { + print OUTPUT $1; + + my $locale_start_spaces = $2 ? $2 : ''; + my $default_spaces = $4 ? $4 : ''; + my $short_spaces = $7 ? $7 : ''; + my $long_spaces = $10 ? $10 : ''; + my $locale_end_spaces = $13 ? $13 : ''; + my $c_default_block = $3 ? $3 : ''; + my $default_string = $6 ? $6 : ''; + my $short_string = $9 ? $9 : ''; + my $long_string = $12 ? $12 : ''; + + print OUTPUT "$locale_start_spaces$c_default_block"; + + $default_string =~ s/\s+/ /g; + $default_string = entity_decode($default_string); + $short_string =~ s/\s+/ /g; + $short_string = entity_decode($short_string); + $long_string =~ s/\s+/ /g; + $long_string = entity_decode($long_string); + + for my $lang (sort keys %po_files_by_lang) + { + my $default_translation = $translations{$lang, $default_string}; + my $short_translation = $translations{$lang, $short_string}; + my $long_translation = $translations{$lang, $long_string}; + + next if (!$default_translation && !$short_translation && + !$long_translation); + + print OUTPUT "\n$locale_start_spaces"; + + print OUTPUT "$default_spaces"; + + if ($default_translation) + { + $default_translation = entity_encode($default_translation); + print OUTPUT "$default_translation"; + } + + print OUTPUT "$short_spaces"; + + if ($short_translation) + { + $short_translation = entity_encode($short_translation); + print OUTPUT "$short_translation"; + } + + print OUTPUT "$long_spaces"; + + if ($long_translation) + { + $long_translation = entity_encode($long_translation); + print OUTPUT "$long_translation"; + } + + print OUTPUT "$locale_end_spaces"; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + +sub rfc822deb_merge_translations +{ + my %encodings = (); + for my $lang (keys %po_files_by_lang) { + $encodings{$lang} = ($UTF8_ARG ? 'UTF-8' : get_po_encoding($po_files_by_lang{$lang})); + } + + my $source; + + $Text::Wrap::huge = 'overflow'; + $Text::Wrap::break = qr/\n|\s(?=\S)/; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">${OUTFILE}" or die; + binmode (OUTPUT) if $^O eq 'MSWin32'; + + while ($source =~ /(^|\n+)(_*)([^:\s]+)(:[ \t]*)(.*?)(?=\n[\S\n]|$)/sg) + { + my $sep = $1; + my $non_translated_line = $3.$4; + my $string = $5; + my $underscore = length($2); + next if $underscore eq 0 && $non_translated_line =~ /^#/; + # Remove [] dummy strings + my $stripped = $string; + $stripped =~ s/\[\s[^\[\]]*\],/,/g if $underscore eq 2; + $stripped =~ s/\[\s[^\[\]]*\]$//; + $non_translated_line .= $stripped; + + print OUTPUT $sep.$non_translated_line; + + if ($underscore) + { + my @str_list = rfc822deb_split($underscore, $string); + + for my $lang (sort keys %po_files_by_lang) + { + my $is_translated = 1; + my $str_translated = ''; + my $first = 1; + + for my $str (@str_list) + { + my $translation = $translations{$lang, $str}; + + if (!$translation) + { + $is_translated = 0; + last; + } + + # $translation may also contain [] dummy + # strings, mostly to indicate an empty string + $translation =~ s/\[\s[^\[\]]*\]$//; + + if ($first) + { + if ($underscore eq 2) + { + $str_translated .= $translation; + } + else + { + $str_translated .= + Text::Tabs::expand($translation) . + "\n"; + } + } + else + { + if ($underscore eq 2) + { + $str_translated .= ', ' . $translation; + } + else + { + $str_translated .= Text::Tabs::expand( + Text::Wrap::wrap(' ', ' ', $translation)) . + "\n .\n"; + } + } + $first = 0; + + # To fix some problems with Text::Wrap::wrap + $str_translated =~ s/(\n )+\n/\n .\n/g; + } + next unless $is_translated; + + $str_translated =~ s/\n \.\n$//; + $str_translated =~ s/\s+$//; + + $_ = $non_translated_line; + s/^(\w+):\s*.*/$sep${1}-$lang.$encodings{$lang}: $str_translated/s; + print OUTPUT; + } + } + } + print OUTPUT "\n"; + + close OUTPUT; + close INPUT; +} + +sub rfc822deb_split +{ + # Debian defines a special way to deal with rfc822-style files: + # when a value contain newlines, it consists of + # 1. a short form (first line) + # 2. a long description, all lines begin with a space, + # and paragraphs are separated by a single dot on a line + # This routine returns an array of all paragraphs, and reformat + # them. + # When first argument is 2, the string is a comma separated list of + # values. + my $type = shift; + my $text = shift; + $text =~ s/^[ \t]//mg; + return (split(/, */, $text, 0)) if $type ne 1; + return ($text) if $text !~ /\n/; + + $text =~ s/([^\n]*)\n//; + my @list = ($1); + my $str = ''; + + for my $line (split (/\n/, $text)) + { + chomp $line; + if ($line =~ /^\.\s*$/) + { + # New paragraph + $str =~ s/\s*$//; + push(@list, $str); + $str = ''; + } + elsif ($line =~ /^\s/) + { + # Line which must not be reformatted + $str .= "\n" if length ($str) && $str !~ /\n$/; + $line =~ s/\s+$//; + $str .= $line."\n"; + } + else + { + # Continuation line, remove newline + $str .= " " if length ($str) && $str !~ /\n$/; + $str .= $line; + } + } + + $str =~ s/\s*$//; + push(@list, $str) if length ($str); + + return @list; +} + +sub quoted_translation +{ + my ($xml_mode, $lang, $string) = @_; + + $string = entity_decode($string) if $xml_mode; + $string =~ s/\\\"/\"/g; + + my $translation = $translations{$lang, $string}; + $translation = $string if !$translation; + $translation = entity_encode($translation) if $xml_mode; + $translation =~ s/\"/\\\"/g; + return $translation +} + +sub quoted_merge_translations +{ + my ($xml_mode) = @_; + + if (!$MULTIPLE_OUTPUT) { + print "Quoted only supports Multiple Output.\n"; + exit(1); + } + + for my $lang (sort keys %po_files_by_lang) { + if ( ! -d $lang ) { + mkdir $lang or -d $lang or die "Cannot create subdirectory $lang: $!\n"; + } + open INPUT, "<${FILE}" or die; + open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n"; + binmode (OUTPUT) if $^O eq 'MSWin32'; + while () + { + s/\"(([^\"]|\\\")*[^\\\"])\"/"\"" . "ed_translation($xml_mode, $lang, $1) . "\""/ge; + print OUTPUT; + } + close OUTPUT; + close INPUT; + } +} --- network-manager-applet-0.7~~svn20081005t082522.orig/intltool-update.in +++ network-manager-applet-0.7~~svn20081005t082522/intltool-update.in @@ -0,0 +1,1164 @@ +#!@INTLTOOL_PERL@ -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +# +# The Intltool Message Updater +# +# Copyright (C) 2000-2003 Free Software Foundation. +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Kenneth Christiansen +# Maciej Stachowiak +# Darin Adler + +## Release information +my $PROGRAM = "intltool-update"; +my $VERSION = "0.37.0"; +my $PACKAGE = "intltool"; + +## Loaded modules +use strict; +use Getopt::Long; +use Cwd; +use File::Copy; +use File::Find; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $DIST_ARG = 0; +my $POT_ARG = 0; +my $HEADERS_ARG = 0; +my $MAINTAIN_ARG = 0; +my $REPORT_ARG = 0; +my $VERBOSE = 0; +my $GETTEXT_PACKAGE = ""; +my $OUTPUT_FILE = ""; + +my @languages; +my %varhash = (); +my %po_files_by_lang = (); + +# Regular expressions to categorize file types. +# FIXME: Please check if the following is correct + +my $xml_support = +"xml(?:\\.in)*|". # http://www.w3.org/XML/ (Note: .in is not required) +"ui|". # Bonobo specific - User Interface desc. files +"lang|". # ? +"glade2?(?:\\.in)*|". # Glade specific - User Interface desc. files (Note: .in is not required) +"scm(?:\\.in)*|". # ? (Note: .in is not required) +"oaf(?:\\.in)+|". # DEPRECATED: Replaces by Bonobo .server files +"etspec|". # ? +"server(?:\\.in)+|". # Bonobo specific +"sheet(?:\\.in)+|". # ? +"schemas(?:\\.in)+|". # GConf specific +"pong(?:\\.in)+|". # DEPRECATED: PONG is not used [by GNOME] any longer. +"kbd(?:\\.in)+|". # GOK specific. +"policy(?:\\.in)+"; # PolicyKit files + +my $ini_support = +"icon(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec +"desktop(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec +"caves(?:\\.in)+|". # GNOME Games specific +"directory(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec +"soundlist(?:\\.in)+|". # GNOME specific +"keys(?:\\.in)+|". # GNOME Mime database specific +"theme(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec +"service(?:\\.in)+"; # DBus specific + +my $buildin_gettext_support = +"c|y|cs|cc|cpp|c\\+\\+|h|hh|gob|py"; + +## Always flush buffer when printing +$| = 1; + +## Sometimes the source tree will be rooted somewhere else. +my $SRCDIR = $ENV{"srcdir"} || "."; +my $POTFILES_in; + +$POTFILES_in = "<$SRCDIR/POTFILES.in"; + +my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null'); + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "dist|d" => \$DIST_ARG, + "pot|p" => \$POT_ARG, + "headers|s" => \$HEADERS_ARG, + "maintain|m" => \$MAINTAIN_ARG, + "report|r" => \$REPORT_ARG, + "verbose|x" => \$VERBOSE, + "gettext-package|g=s" => \$GETTEXT_PACKAGE, + "output-file|o=s" => \$OUTPUT_FILE, + ) or &Console_WriteError_InvalidOption; + +&Console_Write_IntltoolHelp if $HELP_ARG; +&Console_Write_IntltoolVersion if $VERSION_ARG; + +my $arg_count = ($DIST_ARG > 0) + + ($POT_ARG > 0) + + ($HEADERS_ARG > 0) + + ($MAINTAIN_ARG > 0) + + ($REPORT_ARG > 0); + +&Console_Write_IntltoolHelp if $arg_count > 1; + +my $PKGNAME = FindPackageName (); + +# --version and --help don't require a module name +my $MODULE = $GETTEXT_PACKAGE || $PKGNAME || "unknown"; + +if ($POT_ARG) +{ + &GenerateHeaders; + &GeneratePOTemplate; +} +elsif ($HEADERS_ARG) +{ + &GenerateHeaders; +} +elsif ($MAINTAIN_ARG) +{ + &FindLeftoutFiles; +} +elsif ($REPORT_ARG) +{ + &GenerateHeaders; + &GeneratePOTemplate; + &Console_Write_CoverageReport; +} +elsif ((defined $ARGV[0]) && $ARGV[0] =~ /^[a-z]/) +{ + my $lang = $ARGV[0]; + + ## Report error if the language file supplied + ## to the command line is non-existent + &Console_WriteError_NotExisting("$SRCDIR/$lang.po") + if ! -s "$SRCDIR/$lang.po"; + + if (!$DIST_ARG) + { + print "Working, please wait..." if $VERBOSE; + &GenerateHeaders; + &GeneratePOTemplate; + } + &POFile_Update ($lang, $OUTPUT_FILE); + &Console_Write_TranslationStatus ($lang, $OUTPUT_FILE); +} +else +{ + &Console_Write_IntltoolHelp; +} + +exit; + +######### + +sub Console_Write_IntltoolVersion +{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) $VERSION +Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler. + +Copyright (C) 2000-2003 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +sub Console_Write_IntltoolHelp +{ + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... LANGCODE +Updates PO template files and merge them with the translations. + +Mode of operation (only one is allowed): + -p, --pot generate the PO template only + -s, --headers generate the header files in POTFILES.in + -m, --maintain search for left out files from POTFILES.in + -r, --report display a status report for the module + -d, --dist merge LANGCODE.po with existing PO template + +Extra options: + -g, --gettext-package=NAME override PO template name, useful with --pot + -o, --output-file=FILE write merged translation to FILE + -x, --verbose display lots of feedback + --help display this help and exit + --version output version information and exit + +Examples of use: +${PROGRAM} --pot just create a new PO template +${PROGRAM} xy create new PO template and merge xy.po with it + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + +sub echo_n +{ + my $str = shift; + my $ret = `echo "$str"`; + + $ret =~ s/\n$//; # do we need the "s" flag? + + return $ret; +} + +sub POFile_DetermineType ($) +{ + my $type = $_; + my $gettext_type; + + my $xml_regex = "(?:" . $xml_support . ")"; + my $ini_regex = "(?:" . $ini_support . ")"; + my $buildin_regex = "(?:" . $buildin_gettext_support . ")"; + + if ($type =~ /\[type: gettext\/([^\]].*)]/) + { + $gettext_type=$1; + } + elsif ($type =~ /schemas(\.in)+$/) + { + $gettext_type="schemas"; + } + elsif ($type =~ /glade2?(\.in)*$/) + { + $gettext_type="glade"; + } + elsif ($type =~ /scm(\.in)*$/) + { + $gettext_type="scheme"; + } + elsif ($type =~ /keys(\.in)+$/) + { + $gettext_type="keys"; + } + + # bucket types + + elsif ($type =~ /$xml_regex$/) + { + $gettext_type="xml"; + } + elsif ($type =~ /$ini_regex$/) + { + $gettext_type="ini"; + } + elsif ($type =~ /$buildin_regex$/) + { + $gettext_type="buildin"; + } + else + { + $gettext_type="unknown"; + } + + return "gettext\/$gettext_type"; +} + +sub TextFile_DetermineEncoding ($) +{ + my $gettext_code="ASCII"; # All files are ASCII by default + my $filetype=`file $_ | cut -d ' ' -f 2`; + + if ($? eq "0") + { + if ($filetype =~ /^(ISO|UTF)/) + { + chomp ($gettext_code = $filetype); + } + elsif ($filetype =~ /^XML/) + { + $gettext_code="UTF-8"; # We asume that .glade and other .xml files are UTF-8 + } + } + + return $gettext_code; +} + +sub isNotValidMissing +{ + my ($file) = @_; + + return if $file =~ /^\{arch\}\/.*$/; + return if $file =~ /^$varhash{"PACKAGE"}-$varhash{"VERSION"}\/.*$/; +} + +sub FindLeftoutFiles +{ + my (@buf_i18n_plain, + @buf_i18n_xml, + @buf_i18n_xml_unmarked, + @buf_i18n_ini, + @buf_potfiles, + @buf_potfiles_ignore, + @buf_allfiles, + @buf_allfiles_sorted, + @buf_potfiles_sorted, + @buf_potfiles_ignore_sorted + ); + + ## Search and find all translatable files + find sub { + push @buf_i18n_plain, "$File::Find::name" if /\.($buildin_gettext_support)$/; + push @buf_i18n_xml, "$File::Find::name" if /\.($xml_support)$/; + push @buf_i18n_ini, "$File::Find::name" if /\.($ini_support)$/; + push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/; + }, ".."; + find sub { + push @buf_i18n_plain, "$File::Find::name" if /\.($buildin_gettext_support)$/; + push @buf_i18n_xml, "$File::Find::name" if /\.($xml_support)$/; + push @buf_i18n_ini, "$File::Find::name" if /\.($ini_support)$/; + push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/; + }, "$SRCDIR/.." if "$SRCDIR" ne "."; + + open POTFILES, $POTFILES_in or die "$PROGRAM: there's no POTFILES.in!\n"; + @buf_potfiles = grep !/^(#|\s*$)/, ; + close POTFILES; + + foreach (@buf_potfiles) { + s/^\[.*]\s*//; + } + + print "Searching for missing translatable files...\n" if $VERBOSE; + + ## Check if we should ignore some found files, when + ## comparing with POTFILES.in + foreach my $ignore ("POTFILES.skip", "POTFILES.ignore") + { + (-s "$SRCDIR/$ignore") or next; + + if ("$ignore" eq "POTFILES.ignore") + { + print "The usage of POTFILES.ignore is deprecated. Please consider moving the\n". + "content of this file to POTFILES.skip.\n"; + } + + print "Found $ignore: Ignoring files...\n" if $VERBOSE; + open FILE, "<$SRCDIR/$ignore" or die "ERROR: Failed to open $SRCDIR/$ignore!\n"; + + while () + { + push @buf_potfiles_ignore, $_ unless /^(#|\s*$)/; + } + close FILE; + + @buf_potfiles_ignore_sorted = sort (@buf_potfiles_ignore); + } + + foreach my $file (@buf_i18n_plain) + { + my $in_comment = 0; + my $in_macro = 0; + + open FILE, "<$file"; + while () + { + # Handle continued multi-line comment. + if ($in_comment) + { + next unless s-.*\*/--; + $in_comment = 0; + } + + # Handle continued macro. + if ($in_macro) + { + $in_macro = 0 unless /\\$/; + next; + } + + # Handle start of macro (or any preprocessor directive). + if (/^\s*\#/) + { + $in_macro = 1 if /^([^\\]|\\.)*\\$/; + next; + } + + # Handle comments and quoted text. + while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy + { + my $match = $1; + if ($match eq "/*") + { + if (!s-/\*.*?\*/--) + { + s-/\*.*--; + $in_comment = 1; + } + } + elsif ($match eq "//") + { + s-//.*--; + } + else # ' or " + { + if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-) + { + warn "mismatched quotes at line $. in $file\n"; + s-$match.*--; + } + } + } + + if (/\w\.GetString *\(QUOTEDTEXT/) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + ## Remove the first 3 chars and add newline + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + last; + } + + ## C_ N_ Q_ and _ are the macros defined in gi8n.h + if (/[CNQ]?_ *\(QUOTEDTEXT/) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + ## Remove the first 3 chars and add newline + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + last; + } + } + close FILE; + } + + foreach my $file (@buf_i18n_xml) + { + open FILE, "<$file"; + + while () + { + # FIXME: share the pattern matching code with intltool-extract + if (/\s_[-A-Za-z0-9._:]+\s*=\s*\"([^"]+)\"/ || /<_[^>]+>/ || /translatable=\"yes\"/) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + last; + } + } + close FILE; + } + + foreach my $file (@buf_i18n_ini) + { + open FILE, "<$file"; + while () + { + if (/_(.*)=/) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + last; + } + } + close FILE; + } + + foreach my $file (@buf_i18n_xml_unmarked) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + } + + + @buf_allfiles_sorted = sort (@buf_allfiles); + @buf_potfiles_sorted = sort (@buf_potfiles); + + my %in2; + foreach (@buf_potfiles_sorted) + { + s#^$SRCDIR/../##; + s#^$SRCDIR/##; + $in2{$_} = 1; + } + + foreach (@buf_potfiles_ignore_sorted) + { + s#^$SRCDIR/../##; + s#^$SRCDIR/##; + $in2{$_} = 1; + } + + my @result; + + foreach (@buf_allfiles_sorted) + { + my $dummy = $_; + my $srcdir = $SRCDIR; + + $srcdir =~ s#^../##; + $dummy =~ s#^$srcdir/../##; + $dummy =~ s#^$srcdir/##; + $dummy =~ s#_build/##; + if (!exists($in2{$dummy})) + { + push @result, $dummy + } + } + + my @buf_potfiles_notexist; + + foreach (@buf_potfiles_sorted) + { + chomp (my $dummy = $_); + if ("$dummy" ne "" and !(-f "$SRCDIR/../$dummy" or -f "../$dummy")) + { + push @buf_potfiles_notexist, $_; + } + } + + ## Save file with information about the files missing + ## if any, and give information about this procedure. + if (@result + @buf_potfiles_notexist > 0) + { + if (@result) + { + print "\n" if $VERBOSE; + unlink "missing"; + open OUT, ">missing"; + print OUT @result; + close OUT; + warn "\e[1mThe following files contain translations and are currently not in use. Please\e[0m\n". + "\e[1mconsider adding these to the POTFILES.in file, located in the po/ directory.\e[0m\n\n"; + print STDERR @result, "\n"; + warn "If some of these files are left out on purpose then please add them to\n". + "POTFILES.skip instead of POTFILES.in. A file \e[1m'missing'\e[0m containing this list\n". + "of left out files has been written in the current directory.\n"; + } + if (@buf_potfiles_notexist) + { + unlink "notexist"; + open OUT, ">notexist"; + print OUT @buf_potfiles_notexist; + close OUT; + warn "\n" if ($VERBOSE or @result); + warn "\e[1mThe following files do not exist anymore:\e[0m\n\n"; + warn @buf_potfiles_notexist, "\n"; + warn "Please remove them from POTFILES.in. A file \e[1m'notexist'\e[0m\n". + "containing this list of absent files has been written in the current directory.\n"; + } + } + + ## If there is nothing to complain about, notify the user + else { + print "\nAll files containing translations are present in POTFILES.in.\n" if $VERBOSE; + } +} + +sub Console_WriteError_InvalidOption +{ + ## Handle invalid arguments + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit 1; +} + +sub isProgramInPath +{ + my ($file) = @_; + # If either a file exists, or when run it returns 0 exit status + return 1 if ((-x $file) or (system("$file --version >$devnull") == 0)); + return 0; +} + +sub isGNUGettextTool +{ + my ($file) = @_; + # Check that we are using GNU gettext tools + if (isProgramInPath ($file)) + { + my $version = `$file --version`; + return 1 if ($version =~ m/.*\(GNU .*\).*/); + } + return 0; +} + +sub GenerateHeaders +{ + my $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} || "intltool-extract"; + + ## Generate the .h header files, so we can allow glade and + ## xml translation support + if (! isProgramInPath ("$EXTRACT")) + { + print STDERR "\n *** The intltool-extract script wasn't found!" + ."\n *** Without it, intltool-update can not generate files.\n"; + exit; + } + else + { + open (FILE, $POTFILES_in) or die "$PROGRAM: POTFILES.in not found.\n"; + + while () + { + chomp; + next if /^\[\s*encoding/; + + ## Find xml files in POTFILES.in and generate the + ## files with help from the extract script + + my $gettext_type= &POFile_DetermineType ($1); + + if (/\.($xml_support|$ini_support)$/ || /^\[/) + { + s/^\[[^\[].*]\s*//; + + my $filename = "../$_"; + + if ($VERBOSE) + { + system ($EXTRACT, "--update", "--srcdir=$SRCDIR", + "--type=$gettext_type", $filename); + } + else + { + system ($EXTRACT, "--update", "--type=$gettext_type", + "--srcdir=$SRCDIR", "--quiet", $filename); + } + } + } + close FILE; + } +} + +# +# Generate .pot file from POTFILES.in +# +sub GeneratePOTemplate +{ + my $XGETTEXT = $ENV{"XGETTEXT"} || "xgettext"; + my $XGETTEXT_ARGS = $ENV{"XGETTEXT_ARGS"} || ''; + chomp $XGETTEXT; + + if (! isGNUGettextTool ("$XGETTEXT")) + { + print STDERR " *** GNU xgettext is not found on this system!\n". + " *** Without it, intltool-update can not extract strings.\n"; + exit; + } + + print "Building $MODULE.pot...\n" if $VERBOSE; + + open INFILE, $POTFILES_in; + unlink "POTFILES.in.temp"; + open OUTFILE, ">POTFILES.in.temp" or die("Cannot open POTFILES.in.temp for writing"); + + my $gettext_support_nonascii = 0; + + # checks for GNU gettext >= 0.12 + my $dummy = `$XGETTEXT --version --from-code=UTF-8 >$devnull 2>$devnull`; + if ($? == 0) + { + $gettext_support_nonascii = 1; + } + else + { + # urge everybody to upgrade gettext + print STDERR "WARNING: This version of gettext does not support extracting non-ASCII\n". + " strings. That means you should install a version of gettext\n". + " that supports non-ASCII strings (such as GNU gettext >= 0.12),\n". + " or have to let non-ASCII strings untranslated. (If there is any)\n"; + } + + my $encoding = "ASCII"; + my $forced_gettext_code; + my @temp_headers; + my $encoding_problem_is_reported = 0; + + while () + { + next if (/^#/ or /^\s*$/); + + chomp; + + my $gettext_code; + + if (/^\[\s*encoding:\s*(.*)\s*\]/) + { + $forced_gettext_code=$1; + } + elsif (/\.($xml_support|$ini_support)$/ || /^\[/) + { + s/^\[.*]\s*//; + print OUTFILE "../$_.h\n"; + push @temp_headers, "../$_.h"; + $gettext_code = &TextFile_DetermineEncoding ("../$_.h") if ($gettext_support_nonascii and not defined $forced_gettext_code); + } + else + { + print OUTFILE "$SRCDIR/../$_\n"; + $gettext_code = &TextFile_DetermineEncoding ("$SRCDIR/../$_") if ($gettext_support_nonascii and not defined $forced_gettext_code); + } + + next if (! $gettext_support_nonascii); + + if (defined $forced_gettext_code) + { + $encoding=$forced_gettext_code; + } + elsif (defined $gettext_code and "$encoding" ne "$gettext_code") + { + if ($encoding eq "ASCII") + { + $encoding=$gettext_code; + } + elsif ($gettext_code ne "ASCII") + { + # Only report once because the message is quite long + if (! $encoding_problem_is_reported) + { + print STDERR "WARNING: You should use the same file encoding for all your project files,\n". + " but $PROGRAM thinks that most of the source files are in\n". + " $encoding encoding, while \"$_\" is (likely) in\n". + " $gettext_code encoding. If you are sure that all translatable strings\n". + " are in same encoding (say UTF-8), please \e[1m*prepend*\e[0m the following\n". + " line to POTFILES.in:\n\n". + " [encoding: UTF-8]\n\n". + " and make sure that configure.in/ac checks for $PACKAGE >= 0.27 .\n". + "(such warning message will only be reported once.)\n"; + $encoding_problem_is_reported = 1; + } + } + } + } + + close OUTFILE; + close INFILE; + + unlink "$MODULE.pot"; + my @xgettext_argument=("$XGETTEXT", + "--add-comments", + "--directory\=.", + "--default-domain\=$MODULE", + "--flag\=g_strdup_printf:1:c-format", + "--flag\=g_string_printf:2:c-format", + "--flag\=g_string_append_printf:2:c-format", + "--flag\=g_error_new:3:c-format", + "--flag\=g_set_error:4:c-format", + "--flag\=g_markup_printf_escaped:1:c-format", + "--flag\=g_log:3:c-format", + "--flag\=g_print:1:c-format", + "--flag\=g_printerr:1:c-format", + "--flag\=g_printf:1:c-format", + "--flag\=g_fprintf:2:c-format", + "--flag\=g_sprintf:2:c-format", + "--flag\=g_snprintf:3:c-format", + "--flag\=g_scanner_error:2:c-format", + "--flag\=g_scanner_warn:2:c-format", + "--output\=$MODULE\.pot", + "--files-from\=\.\/POTFILES\.in\.temp"); + my $XGETTEXT_KEYWORDS = &FindPOTKeywords; + push @xgettext_argument, $XGETTEXT_KEYWORDS; + my $MSGID_BUGS_ADDRESS = &FindMakevarsBugAddress; + push @xgettext_argument, "--msgid-bugs-address\=\"$MSGID_BUGS_ADDRESS\"" if $MSGID_BUGS_ADDRESS; + push @xgettext_argument, "--from-code\=$encoding" if ($gettext_support_nonascii); + push @xgettext_argument, $XGETTEXT_ARGS if $XGETTEXT_ARGS; + my $xgettext_command = join ' ', @xgettext_argument; + + # intercept xgettext error message + print "Running $xgettext_command\n" if $VERBOSE; + my $xgettext_error_msg = `$xgettext_command 2>\&1`; + my $command_failed = $?; + + unlink "POTFILES.in.temp"; + + print "Removing generated header (.h) files..." if $VERBOSE; + unlink foreach (@temp_headers); + print "done.\n" if $VERBOSE; + + if (! $command_failed) + { + if (! -e "$MODULE.pot") + { + print "None of the files in POTFILES.in contain strings marked for translation.\n" if $VERBOSE; + } + else + { + print "Wrote $MODULE.pot\n" if $VERBOSE; + } + } + else + { + if ($xgettext_error_msg =~ /--from-code/) + { + # replace non-ASCII error message with a more useful one. + print STDERR "ERROR: xgettext failed to generate PO template file because there is non-ASCII\n". + " string marked for translation. Please make sure that all strings marked\n". + " for translation are in uniform encoding (say UTF-8), then \e[1m*prepend*\e[0m the\n". + " following line to POTFILES.in and rerun $PROGRAM:\n\n". + " [encoding: UTF-8]\n\n"; + } + else + { + print STDERR "$xgettext_error_msg"; + if (-e "$MODULE.pot") + { + # is this possible? + print STDERR "ERROR: xgettext failed but still managed to generate PO template file.\n". + " Please consult error message above if there is any.\n"; + } + else + { + print STDERR "ERROR: xgettext failed to generate PO template file. Please consult\n". + " error message above if there is any.\n"; + } + } + exit (1); + } +} + +sub POFile_Update +{ + -f "$MODULE.pot" or die "$PROGRAM: $MODULE.pot does not exist.\n"; + + my $MSGMERGE = $ENV{"MSGMERGE"} || "msgmerge"; + my ($lang, $outfile) = @_; + + if (! isGNUGettextTool ("$MSGMERGE")) + { + print STDERR " *** GNU msgmerge is not found on this system!\n". + " *** Without it, intltool-update can not extract strings.\n"; + exit; + } + + print "Merging $SRCDIR/$lang.po with $MODULE.pot..." if $VERBOSE; + + my $infile = "$SRCDIR/$lang.po"; + $outfile = "$SRCDIR/$lang.po" if ($outfile eq ""); + + # I think msgmerge won't overwrite old file if merge is not successful + system ("$MSGMERGE", "-o", $outfile, $infile, "$MODULE.pot"); +} + +sub Console_WriteError_NotExisting +{ + my ($file) = @_; + + ## Report error if supplied language file is non-existing + print STDERR "$PROGRAM: $file does not exist!\n"; + print STDERR "Try '$PROGRAM --help' for more information.\n"; + exit; +} + +sub GatherPOFiles +{ + my @po_files = glob ("./*.po"); + + @languages = map (&POFile_GetLanguage, @po_files); + + foreach my $lang (@languages) + { + $po_files_by_lang{$lang} = shift (@po_files); + } +} + +sub POFile_GetLanguage ($) +{ + s/^(.*\/)?(.+)\.po$/$2/; + return $_; +} + +sub Console_Write_TranslationStatus +{ + my ($lang, $output_file) = @_; + my $MSGFMT = $ENV{"MSGFMT"} || "msgfmt"; + + if (! isGNUGettextTool ("$MSGFMT")) + { + print STDERR " *** GNU msgfmt is not found on this system!\n". + " *** Without it, intltool-update can not extract strings.\n"; + exit; + } + + $output_file = "$SRCDIR/$lang.po" if ($output_file eq ""); + + system ("$MSGFMT", "-o", "$devnull", "--verbose", $output_file); +} + +sub Console_Write_CoverageReport +{ + my $MSGFMT = $ENV{"MSGFMT"} || "msgfmt"; + + if (! isGNUGettextTool ("$MSGFMT")) + { + print STDERR " *** GNU msgfmt is not found on this system!\n". + " *** Without it, intltool-update can not extract strings.\n"; + exit; + } + + &GatherPOFiles; + + foreach my $lang (@languages) + { + print STDERR "$lang: "; + &POFile_Update ($lang, ""); + } + + print STDERR "\n\n * Current translation support in $MODULE \n\n"; + + foreach my $lang (@languages) + { + print STDERR "$lang: "; + system ("$MSGFMT", "-o", "$devnull", "--verbose", "$SRCDIR/$lang.po"); + } +} + +sub SubstituteVariable +{ + my ($str) = @_; + + # always need to rewind file whenever it has been accessed + seek (CONF, 0, 0); + + # cache each variable. varhash is global to we can add + # variables elsewhere. + while () + { + if (/^(\w+)=(.*)$/) + { + ($varhash{$1} = $2) =~ s/^["'](.*)["']$/$1/; + } + } + + if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/) + { + my $rest = $3; + my $untouched = $1; + my $sub = ""; + # Ignore recursive definitions of variables + $sub = $varhash{$2} if defined $varhash{$2} and $varhash{$2} !~ /\${?$2}?/; + + return SubstituteVariable ("$untouched$sub$rest"); + } + + # We're using Perl backticks ` and "echo -n" here in order to + # expand any shell escapes (such as backticks themselves) in every variable + return echo_n ($str); +} + +sub CONF_Handle_Open +{ + my $base_dirname = getcwd(); + $base_dirname =~ s@.*/@@; + + my ($conf_in, $src_dir); + + if ($base_dirname =~ /^po(-.+)?$/) + { + if (-f "Makevars") + { + my $makefile_source; + + local (*IN); + open (IN, ") + { + if (/^top_builddir[ \t]*=/) + { + $src_dir = $_; + $src_dir =~ s/^top_builddir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/; + + chomp $src_dir; + if (-f "$src_dir" . "/configure.ac") { + $conf_in = "$src_dir" . "/configure.ac" . "\n"; + } else { + $conf_in = "$src_dir" . "/configure.in" . "\n"; + } + last; + } + } + close IN; + + $conf_in || die "Cannot find top_builddir in Makevars."; + } + elsif (-f "$SRCDIR/../configure.ac") + { + $conf_in = "$SRCDIR/../configure.ac"; + } + elsif (-f "$SRCDIR/../configure.in") + { + $conf_in = "$SRCDIR/../configure.in"; + } + else + { + my $makefile_source; + + local (*IN); + open (IN, ") + { + if (/^top_srcdir[ \t]*=/) + { + $src_dir = $_; + $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/; + + chomp $src_dir; + $conf_in = "$src_dir" . "/configure.in" . "\n"; + + last; + } + } + close IN; + + $conf_in || die "Cannot find top_srcdir in Makefile."; + } + + open (CONF, "<$conf_in"); + } + else + { + print STDERR "$PROGRAM: Unable to proceed.\n" . + "Make sure to run this script inside the po directory.\n"; + exit; + } +} + +sub FindPackageName +{ + my $version; + my $domain = &FindMakevarsDomain; + my $name = $domain || "untitled"; + + &CONF_Handle_Open; + + my $conf_source; { + local (*IN); + open (IN, "<&CONF") || return $name; + seek (IN, 0, 0); + local $/; # slurp mode + $conf_source = ; + close IN; + } + + # priority for getting package name: + # 1. GETTEXT_PACKAGE + # 2. first argument of AC_INIT (with >= 2 arguments) + # 3. first argument of AM_INIT_AUTOMAKE (with >= 2 argument) + + # /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m + # the \s makes this not work, why? + if ($conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+),([^,\)]+)/m) + { + ($name, $version) = ($1, $2); + $name =~ s/[\[\]\s]//g; + $version =~ s/[\[\]\s]//g; + $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/); + $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/); + $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/); + $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/); + } + + if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)/m) + { + ($name, $version) = ($1, $2); + $name =~ s/[\[\]\s]//g; + $version =~ s/[\[\]\s]//g; + $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/); + $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/); + $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/); + $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/); + } + + # \s makes this not work, why? + $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\n\]]+)/m; + + # m4 macros AC_PACKAGE_NAME, AC_PACKAGE_VERSION etc. have same value + # as corresponding $PACKAGE_NAME, $PACKAGE_VERSION etc. shell variables. + $name =~ s/\bAC_PACKAGE_/\$PACKAGE_/g; + + $name = $domain if $domain; + + $name = SubstituteVariable ($name); + $name =~ s/^["'](.*)["']$/$1/; + + return $name if $name; +} + + +sub FindPOTKeywords +{ + + my $keywords = "--keyword\=\_ --keyword\=N\_ --keyword\=U\_ --keyword\=Q\_"; + my $varname = "XGETTEXT_OPTIONS"; + my $make_source; { + local (*IN); + open (IN, "; + close IN; + } + + $keywords = $1 if $make_source =~ /^$varname[ ]*=\[?([^\n\]]+)/m; + + return $keywords; +} + +sub FindMakevarsDomain +{ + + my $domain = ""; + my $makevars_source; { + local (*IN); + open (IN, "; + close IN; + } + + $domain = $1 if $makevars_source =~ /^DOMAIN[ ]*=\[?([^\n\]\$]+)/m; + $domain =~ s/^\s+//; + $domain =~ s/\s+$//; + + return $domain; +} + +sub FindMakevarsBugAddress +{ + + my $address = ""; + my $makevars_source; { + local (*IN); + open (IN, "; + close IN; + } + + $address = $1 if $makevars_source =~ /^MSGID_BUGS_ADDRESS[ ]*=\[?([^\n\]\$]+)/m; + $address =~ s/^\s+//; + $address =~ s/\s+$//; + + return $address; +} --- network-manager-applet-0.7~~svn20081005t082522.orig/aclocal.m4 +++ network-manager-applet-0.7~~svn20081005t082522/aclocal.m4 @@ -0,0 +1 @@ +# empty --- network-manager-applet-0.7~~svn20081005t082522.orig/po/Makefile.in.in +++ network-manager-applet-0.7~~svn20081005t082522/po/Makefile.in.in @@ -0,0 +1,218 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. +# +# - Modified by Owen Taylor to use GETTEXT_PACKAGE +# instead of PACKAGE and to look for po2tbl in ./ not in intl/ +# +# - Modified by jacob berkman to install +# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize +# +# - Modified by Rodney Dawes for use with intltool +# +# We have the following line for use by intltoolize: +# INTLTOOL_MAKEFILE + +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = @datadir@ +datarootdir = @datarootdir@ +libdir = @libdir@ +DATADIRNAME = @DATADIRNAME@ +itlocaledir = $(prefix)/$(DATADIRNAME)/locale +subdir = po +install_sh = @install_sh@ +# Automake >= 1.8 provides @mkdir_p@. +# Until it can be supposed, use the safe fallback: +mkdir_p = $(install_sh) -d + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = @XGETTEXT@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist +GENPOT = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot + +ALL_LINGUAS = @ALL_LINGUAS@ + +PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; fi) + +USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep ^$$lang$$ $(srcdir)/LINGUAS`" -o -n "`echo $$ALINGUAS|grep ' ?$$lang ?'`"; then printf "$$lang "; fi; done; fi) + +USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done) + +POFILES=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done) + +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(POFILES) +EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS + +POTFILES = \ +# This comment gets stripped out + +CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done) + +.SUFFIXES: +.SUFFIXES: .po .pox .gmo .mo .msg .cat + +.po.pox: + $(MAKE) $(GETTEXT_PACKAGE).pot + $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && gencat $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: $(CATALOGS) +all-no: + +$(GETTEXT_PACKAGE).pot: $(POTFILES) + $(GENPOT) + +install: install-data +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + $(mkdir_p) $(DESTDIR)$(itlocaledir) + linguas="$(USE_LINGUAS)"; \ + for lang in $$linguas; do \ + dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $$dir; \ + if test -r $$lang.gmo; then \ + $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ + echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ + echo "installing $(srcdir)/$$lang.gmo as" \ + "$$dir/$(GETTEXT_PACKAGE).mo"; \ + fi; \ + if test -r $$lang.gmo.m; then \ + $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \ + echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \ + else \ + if test -r $(srcdir)/$$lang.gmo.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \ + $$dir/$(GETTEXT_PACKAGE).mo.m; \ + echo "installing $(srcdir)/$$lang.gmo.m as" \ + "$$dir/$(GETTEXT_PACKAGE).mo.m"; \ + else \ + true; \ + fi; \ + fi; \ + done + +# Empty stubs to satisfy archaic automake needs +dvi info tags TAGS ID: + +# Define this as empty until I found a useful application. +install-exec installcheck: + +uninstall: + linguas="$(USE_LINGUAS)"; \ + for lang in $$linguas; do \ + rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \ + rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \ + done + +check: all $(GETTEXT_PACKAGE).pot + rm -f missing notexist + srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m + if [ -r missing -o -r notexist ]; then \ + exit 1; \ + fi + +mostlyclean: + rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp + rm -f .intltool-merge-cache + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES stamp-it + rm -f *.mo *.msg *.cat *.cat.m *.gmo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f Makefile.in.in + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: $(DISTFILES) + dists="$(DISTFILES)"; \ + extra_dists="$(EXTRA_DISTFILES)"; \ + for file in $$extra_dists; do \ + test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \ + done; \ + for file in $$dists; do \ + test -f $$file || file="$(srcdir)/$$file"; \ + ln $$file $(distdir) 2> /dev/null \ + || cp -p $$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(GETTEXT_PACKAGE).pot + tmpdir=`pwd`; \ + linguas="$(USE_LINGUAS)"; \ + for lang in $$linguas; do \ + echo "$$lang:"; \ + result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \ + if $$result; then \ + if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.gmo failed!"; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi; \ + done + +Makefile POTFILES: stamp-it + @if test ! -f $@; then \ + rm -f stamp-it; \ + $(MAKE) stamp-it; \ + fi + +stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/network-manager-applet.manpages +++ network-manager-applet-0.7~~svn20081005t082522/debian/network-manager-applet.manpages @@ -0,0 +1 @@ +debian/nm-applet.1 --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/nm-applet.sgml +++ network-manager-applet-0.7~~svn20081005t082522/debian/nm-applet.sgml @@ -0,0 +1,100 @@ + manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + + + The docbook-to-man binary is found in the docbook-to-man package. + Please remember that if you create the nroff version in one of the + debian/rules file targets (such as build), you will need to include + docbook-to-man in your Build-Depends control field. + + --> + + + 8 February, 2006"> + + + GNU"> + GPL"> +]> + + + +
+ giskard@autistici.org; +
+ + Riccardo + Setti + + + 2006 + Riccardo Setti + + &date; +
+ + nm-applet + 1 + + + &package; + + Network management framework + + + + &package; + + + + DESCRIPTION + + &package; is the GNOME front-end for NetworkManager + It is a systray applet which will display an icon in GNOME's notification area but it + also works for other desktop environments which provide a systray like KDE or XFCE. + &package; shows a list of available networks and allows you to easily switch between them. For encrypted networks it + will prompt you for the key/passphrase and you can optionally store them in the gnome-keyring so you don't have to + type them again. + + + SEE ALSO + + NetworkManager (1). nm-vpn-properties (1) + + More Information about NetworkManager can be found at + http://www.gnome.org/projects/NetworkManager/ . + + + AUTHOR + + This manual page was written by Riccardo Setti giskard@autistici.org for + the Debian system. + + + +
+ + --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/changelog +++ network-manager-applet-0.7~~svn20081005t082522/debian/changelog @@ -0,0 +1,238 @@ +network-manager-applet (0.7~~svn20081005t082522-0ubuntu1) intrepid; urgency=low + + * new upstream snapshot Sun 2008-10-05 08:25:22 +0000 (rev 793) + * adjust mbca patch for changed upstream code base + - update debian/patches/add_libmbca_support.patch + + -- Alexander Sack Mon, 06 Oct 2008 13:41:27 +0200 + +network-manager-applet (0.7~~svn20080927t101113-0ubuntu1) intrepid; urgency=low + + * new upstream snapshot Sat 2008-09-27 10:11:13 +0000 (rev 776) + [ Antti Kaijanmäki ] + * added support for Mobile Broadband Configuration Assistant: + - added debian/patches/add_libmbca_support.patch + - updated debian/patches/series + - added libmbca-dev build-dependency to debian/control + - added --with-libmbca to DEB_CONFIGURE_EXTRA_FLAGS in debian/control + + [ Alexander Sack ] + * refresh libmbca patch using quilt to prevent diff pollution in future. + (quilt refresh --diffstat --no-timestamps -U8) + - update debian/patches/add_libmbca_support.patch + * generate a uuid for NMSettingConnection which was introduced by recent + network manager dbus API changes. + - update debian/patches/add_libmbca_support.patch + * fix libmbca setting the dialup string instead of the proper number (*99#) + for GSM modems + - update debian/patches/add_libmbca_support.patch + * add new parameter to add_connection call in mbca patch and strip trailing + whitespaces uses quilt refresh + - update debian/patches/add_libmbca_support.patch + * bump build-depends and depends bar on network-manager bits to + >= 0.7~~svn20080928 + - update debian/control + * explicitly set connection scope for mbca created connections to + NM_CONNECTION_SCOPE_USER + - update debian/patches/add_libmbca_support.patch + * add libmbca0 to Recommends + - update debian/control + + -- Alexander Sack Mon, 29 Sep 2008 22:15:13 +0200 + +network-manager-applet (0.7~~svn20080907t033843-0ubuntu2) intrepid; urgency=low + + * new upstream snapshot Sun 2008-09-07 03:38:43 +0000 (rev 743) + * adjust versioned (build-)depends on network-manager packages to + >= 0.7~~svn20080908 + - update debian/control + + -- Alexander Sack Tue, 09 Sep 2008 16:42:23 +0200 + +network-manager-applet (0.7~~svn20080817t183748-0ubuntu1) intrepid; urgency=low + + * new upstream snapshot Sun 2008-08-17 18:37:48 +0000 (rev 723) + * drop patches applied upstream: + - delete debian/patches/01_gcc43.patch + - update debian/patches/series + * bump build dependency versions on network-manager-dev and friends to (>= + 0.7~~svn20080812) + - update debian/control + * use full path for vpn auth-dialog's as provided by the .name key file in + $sysconfdir/NetworkManager/VPN/ + - add debian/patches/20_use_full_vpn_dialog_service_name_path.patch + - update debian/patches/series + + -- Alexander Sack Mon, 18 Aug 2008 21:32:15 +0200 + +network-manager-applet (0.7~~svn20080721t051503-0ubuntu1) intrepid; urgency=low + + * new upstream snapshot Mon 2008-07-21 05:15:03 +0000 (bzr trunk rev673) + * drop manual network config patches - default connection editor is NM + - delete debian/patches/01_static_network-admin.patch + - delete debian/patches/03_manual_config_available_when_connected.patch + - delete debian/patches/13_custom-network-admin.diff + - update debian/patches/series + * fix gcc 4.3 build failures + - add debian/patches/01_gcc43.patch + - update debian/patches/series + * higher network-manager versions for build and binary depends (>= + 0.7~~svn20080720t224551) + - update debian/control + + -- Alexander Sack Thu, 07 Aug 2008 01:54:01 +0200 + +network-manager-applet (0.7~~svn20080121t194048-0ubuntu0~pre6) hardy; urgency=low + + * package 0.7 svn snapshot + * add automake1.9 to Build-Depends + - update debian/control + * add quilt to Build-Depends + - update debian/control + * add libtool to Build-Depends + - update debian/control + * add gnome-common to Build-Depends + - update debian/control + * add libnotify-dev to Build-Depends + - update debian/control + * add libgnutls-dev to Build-Depends and pass --with-gnutls and + --without-nss to configure explicitly + - update debian/control + - update debian/rules + * make libnm-util-dev build dependency versioned to only build against + versions that come with libnm-util1 + - update debian/control + * include empty aclocal.m4 file to make cdbs trigger aclocal auto run + - add aclocal.m4 + * switch to use quilt as patchsystem + - add debian/patches/series + - update debian/rules + * unfold Build-Depends and Depends in debian/control to improve legability + of patches + - update debian/control + * bump {Build-}Depends: version for network-manager and friends to a + reasonable value (>= 0.7~~svn20080121t191418+eni1-0ubuntu0~pre6) + - update debian/control + * remove debian/network-manager-gnome/usr/include on install + - update debian/rules + + -- Alexander Sack Tue, 22 Jan 2008 17:56:32 +0000 + +network-manager-applet (0.6.5-0ubuntu11) hardy; urgency=low + + * apply patch to drop gnome-runtime dependencies (LP: #136945) - patch by Jani + Monoses + - add debian/patches/06_drop_libgnome.patch + - add debian/patches/99_autoconf_update.patch + * don't use gksu in hardy anymore - policy kit hooray! (LP: #176222) + - update debian/patches/01_static_network-admin.patch + - update debian/patches/13_custom-network-admin.diff + + [ TJ ] + * debian/patches/15_lp124336_missing_prototype_causes_connect_to_other_networks_sigsegv.patch: + Fix SIGSEGV caused by pointer>int>pointer conversion on x86_64. (LP: #124336) + + -- Alexander Sack Wed, 09 Jan 2008 13:15:10 +0100 + +network-manager-applet (0.6.5-0ubuntu10) gutsy; urgency=low + + * debian/control: add missing depends on gksu to allow manual + network-configuration even for minimal ubuntu flavours, like the UME. + * debian/patches/13_custom-network-admin.diff: use BINDIR "/" MANUAL_CONF_FILE + when its available on the system. (LP: #145625) + * debian/rules: apply previously forgotten hunk to install network manager + applet autostart file to /etc/xdg/autostart/ from LP: #95064. + * debian/patches/14_lp123808_dont_start_applet_on_ltsp_client.patch: don't + start nm-applet on ltsp client. (LP: #123808) + + -- Alexander Sack Tue, 02 Oct 2007 20:58:18 +0200 + +network-manager-applet (0.6.5-0ubuntu9) gutsy; urgency=low + + * debian/patches/11_lp95064-enable-xdg-autostart-for-xfce.patch: enable + autostart of nm-applet for XFCE nm-applet.desktop. (LP: #95064) + * debian/patches/12_lp101978-connection-info-hide-on-delete-event.patch: + hide connection info on delete-event; patch by Dima Korzhevin. + (LP: #101978). + + -- Alexander Sack Wed, 19 Sep 2007 18:24:28 +0200 + +network-manager-applet (0.6.5-0ubuntu8) gutsy; urgency=low + + * set Maintainer to ubuntu-core-dev + * add XS-Vcs-Bzr tag to point apt-get to the correct branch + + -- Reinhard Tartler Thu, 26 Jul 2007 15:55:06 +0200 + +network-manager-applet (0.6.5-0ubuntu7) gutsy; urgency=low + + * add 04_nm-vpn-properties_path again, nm-vpn-properties has been moved + back again. LP: #127844 + + -- Reinhard Tartler Thu, 26 Jul 2007 11:05:45 +0200 + +network-manager-applet (0.6.5-0ubuntu6) gutsy; urgency=low + + * remove 04_nm-vpn-properties_path.patch. nm-vpn-properties now + installed in /usr/bin again. + + -- Reinhard Tartler Thu, 05 Jul 2007 10:25:15 +0200 + +network-manager-applet (0.6.5-0ubuntu5) gutsy; urgency=low + + * debian/control: + - Build-Depends on intltool so the translation template updated + (LP: #122547) + + -- Sebastien Bacher Thu, 28 Jun 2007 21:32:29 +0200 + +network-manager-applet (0.6.5-0ubuntu4) gutsy; urgency=low + + * debian/patches/01_static_network-admin.patch: fix by Peter + Clifton; adding NULL check to stop nm-applet from crashing + and make encrypted wifi work. (LP: #121228) + + -- Alexander Sack Wed, 27 Jun 2007 12:34:03 +0200 + +network-manager-applet (0.6.5-0ubuntu3) gutsy; urgency=low + + * Re-import applet patches from network-manager + + * debian/control: tighten build-depends on network-manager to + >= 0.6.5-0ubuntu3 + + * Make patches apply against applet sources + drop patches that have + been applied upstream: + - debian/patches/01_static_network-admin.patch: fix diff path for + new source layout: gnome/applet -> src/ + update line numbers. + - debian/patches/02_manual_means_always_online.diff: fix diff path + for new source layout: gnome/applet -> src/ + update line numbers; + drop diffs for sources not in this tarball: src/NetworkManagerDbus.c, + src/NetworkManagerMain.h and src/nm-device.c. + - debian/patches/03_manual_config_available_when_connected.patch: fix + diff path for new source layout: gnome/applet -> src/ + update line + numbers. + - debian/patches/04_nm-vpn-properties_path.patch: nm-vpn-properties + are shipped in network-manager pkglibdir + - debian/patches/10-po_fr.patch: all but one translation fixes were applied + upstream. + + -- Alexander Sack Tue, 26 Jun 2007 10:52:45 +0200 + +network-manager-applet (0.6.5-0ubuntu2) gutsy; urgency=low + + * Added missing dep network-manager + + -- Anthony Mercatante Fri, 22 Jun 2007 18:24:22 +0200 + +network-manager-applet (0.6.5-0ubuntu1) gutsy; urgency=low + + * Initial release + * Added 21_manual_means_always_online.diff to "patches-not-applied" + The gnome applet has been splitted from n-m code, and patch needs + to be rewritten + * Added 04_nm-vpn-properties_path.patch + Fixes path to nm-vpn-properties according to the changes we've done + to network-manager package due to bad source splitting + + -- Anthony Mercatante Fri, 15 Jun 2007 12:46:22 +0200 --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/copyright +++ network-manager-applet-0.7~~svn20081005t082522/debian/copyright @@ -0,0 +1,59 @@ +This package was debianized by Anthony Mercatante on +Fri, 15 Jun 2007 11:54:56 +0200. + +It was downloaded from http://ftp.acc.umu.se/pub/GNOME/sources/network-manager-applet/ + +Upstream author: + Dan Williams + +Copyright holders: + Copyright 2004-2005 Red Hat, Inc. + Copyright 2006 Thiago Jung Bauermann + Copyright 1999, 2000 Eazel, Inc. + Copyright 2002 Anders Carlsson + Copyright 2006 Novell, Inc. + Copyright 2006 Thiago Jung Bauermann + Copyright 2001, 2002 Free Software Foundation + +License: +All the software: + + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. + + +eggtrayicon.c, eggtrayicon.h: + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Debian systems, the complete text of the GNU Lesser General +Public License can be found in `/usr/share/common-licenses/LGPL'. + +menu-items.c: + This also uses code from eel-vfs-extentions available under the LGPL --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/compat +++ network-manager-applet-0.7~~svn20081005t082522/debian/compat @@ -0,0 +1 @@ +5 --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/control +++ network-manager-applet-0.7~~svn20081005t082522/debian/control @@ -0,0 +1,53 @@ +Source: network-manager-applet +Section: gnome +Priority: optional +Maintainer: Ubuntu Core Developers +Original-Maintainer: Anthony Mercatante +Build-Depends: debhelper (>= 5.0.37), + automake1.9, + libtool, + cdbs, + libgnome-keyring-dev, + libgnomeui-dev, + libpanel-applet2-dev, + libglade2-dev, + libgconf2-dev, + network-manager-dev (>= 0.7~~svn20080928), + libnm-util-dev (>= 0.7~~svn20080928), + libnm-glib-dev (>= 0.7~~svn20080928), + libiw-dev, + libxml-parser-perl, + docbook-to-man, + quilt, + libnotify-dev, + gnome-common, + libnss3-dev, + libpolkit-gnome-dev, + intltool, + libmbca0-dev +Standards-Version: 3.7.2 +XS-Vcs-Bzr: https://code.launchpad.net/~ubuntu-core-dev/network-manager/gnome.ubuntu.0.6.x + +Package: network-manager-gnome +Architecture: any +Depends: ${shlibs:Depends}, + ${misc:Depends}, + network-manager (>= 0.7~~svn20080928), + gksu +Recommends: notification-daemon, libmbca0 +Description: network management framework (GNOME frontend) + NetworkManager attempts to keep an active network connection available at all + times. It is intended only for the desktop use-case, and is not intended for + usage on servers. The point of NetworkManager is to make networking + configuration and setup as painless and automatic as possible. If using DHCP, + NetworkManager is _intended_ to replace default routes, obtain IP addresses + from a DHCP server, and change nameservers whenever it sees fit. + . + This package contains a systray applet for GNOME's notification area but it + also works for other desktop environments which provide a systray like KDE + or XFCE. + It displays the available networks and allows to easily switch between them. + For encrypted networks it will prompt the user for the key/passphrase and it + can optionally store them in the gnome-keyring. + . + Homepage: http://www.gnome.org/projects/NetworkManager/ --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/rules +++ network-manager-applet-0.7~~svn20081005t082522/debian/rules @@ -0,0 +1,27 @@ +#!/usr/bin/make -f + +DEB_AUTO_UPDATE_LIBTOOL = pre +DEB_AUTO_UPDATE_AUTOHEADER = 2.50 +DEB_AUTO_UPDATE_ACLOCAL = 1.9 +DEB_AUTO_UPDATE_AUTOMAKE = 1.9 -a -c -f +DEB_AUTO_UPDATE_AUTOCONF = 2.50 + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/patchsys-quilt.mk +include /usr/share/cdbs/1/class/gnome.mk + +DEB_CONFIGURE_EXTRA_FLAGS = \ + --without-gnutls \ + --with-nss \ + --with-mbca \ + $(NULL) + +build/network-manager-gnome:: + /usr/bin/docbook-to-man debian/nm-applet.sgml > debian/nm-applet.1 + +common-binary-arch:: + rm -rf debian/network-manager-gnome/usr/include/ + +clean:: + rm -f po/*.gmo + rm -f debian/*.1 --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/patches/14_lp123808_dont_start_applet_on_ltsp_client.patch +++ network-manager-applet-0.7~~svn20081005t082522/debian/patches/14_lp123808_dont_start_applet_on_ltsp_client.patch @@ -0,0 +1,11 @@ +--- network-manager-applet-0.6.5/src/applet.c.orig 2007-10-02 20:53:36.000000000 +0200 ++++ network-manager-applet-0.6.5/src/applet.c 2007-10-02 20:54:46.000000000 +0200 +@@ -132,7 +132,7 @@ static void nma_init (NMApplet *applet) + applet->animation_step = 0; + glade_gnome_init (); + +- if (!nma_icons_init (applet)) ++ if ((!nma_icons_init (applet)) || (g_getenv("LTSP_CLIENT"))) + return; + + /* gtk_window_set_default_icon_from_file (ICONDIR"/NMApplet/wireless-applet.png", NULL); */ --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/patches/series +++ network-manager-applet-0.7~~svn20081005t082522/debian/patches/series @@ -0,0 +1,2 @@ +add_libmbca_support.patch +20_use_full_vpn_dialog_service_name_path.patch --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/patches/add_libmbca_support.patch +++ network-manager-applet-0.7~~svn20081005t082522/debian/patches/add_libmbca_support.patch @@ -0,0 +1,1086 @@ +--- + configure.ac | 10 + + src/applet-device-gsm.c | 262 ++++++++++++++++++++++++++ + src/applet.c | 67 ++++++ + src/applet.h | 30 +++ + src/connection-editor/nm-connection-editor.c | 1 + src/connection-editor/nm-connection-list.c | 268 +++++++++++++++++++++++---- + src/connection-editor/nm-connection-list.h | 14 + + 7 files changed, 618 insertions(+), 34 deletions(-) + +Index: network-manager-applet-0.7~~svn20080927t101113/src/applet-device-gsm.c +=================================================================== +--- network-manager-applet-0.7~~svn20080927t101113.orig/src/applet-device-gsm.c ++++ network-manager-applet-0.7~~svn20080927t101113/src/applet-device-gsm.c +@@ -32,45 +32,239 @@ + #include + #include + #include + #include + #include + #include + #include + ++#ifdef WITH_MBCA ++#include ++#include ++#include ++#include ++#endif ++ + #include "applet.h" + #include "applet-device-gsm.h" + #include "utils.h" + + typedef struct { + NMApplet *applet; + NMDevice *device; + NMConnection *connection; + } GSMMenuItemInfo; + + static void + gsm_menu_item_info_destroy (gpointer data) + { + g_slice_free (GSMMenuItemInfo, data); + } + ++#ifdef WITH_MBCA ++ ++static void ++assistant_state_changed_cb (MBCAAssistant* assistant, ++ MBCAAssistantState state, ++ gpointer data) ++{ ++ NMApplet *applet = data; ++ GSList* iter; ++ ++ NMAGConfConnection *exported; ++ ++ NMConnection *connection; ++ NMSettingGsm *s_gsm; ++ NMSettingSerial *s_serial; ++ NMSettingPPP *s_ppp; ++ NMSettingConnection *s_con; ++ ++ NMSettingIP4Config* ipv4conf; ++ gboolean ignore_auto_dns = FALSE; ++ GArray *dns_servers = FALSE; ++ const char *method; ++ ++ MBCAConfiguration* conf; ++ ++ if (!applet_open_mbca (applet)) ++ g_return_if_reached (); /* this cb should not be called without ++ * libmbca */ ++ ++ switch (state) ++ { ++ case MBCA_STATE_READY: ++ case MBCA_STATE_RUNNING: ++ { ++ break; ++ } ++ case MBCA_STATE_DONE: ++ { ++ conf = applet->mbca_assistant_get_configuration_func (assistant); ++ connection = nm_connection_new (); ++ ++ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); ++ nm_connection_add_setting (connection, NM_SETTING (s_con)); ++ ++ ipv4conf = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); ++ nm_connection_add_setting (connection, NM_SETTING (ipv4conf)); ++ ++ s_con->id = g_strdup (conf->name); ++ s_con->type = g_strdup (NM_SETTING_GSM_SETTING_NAME); ++ s_con->uuid = nm_utils_uuid_generate (); ++ s_con->autoconnect = FALSE; ++ ++ /* Serial setting */ ++ s_serial = (NMSettingSerial *) nm_setting_serial_new (); ++ s_serial->baud = 115200; ++ s_serial->bits = 8; ++ s_serial->parity = 'n'; ++ s_serial->stopbits = 1; ++ nm_connection_add_setting (connection, NM_SETTING (s_serial)); ++ ++ method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; ++ ++ s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); ++ s_gsm->number = g_strdup ("*99#"); ++ ++ s_gsm->apn = g_strdup (conf->provider->gsm.apn); ++ ++ s_gsm->username = g_strdup (conf->provider->username); ++ s_gsm->password = g_strdup (conf->provider->password); ++ ++ if (conf->provider->dns1) { ++ struct in_addr tmp_addr; ++ ignore_auto_dns = TRUE; ++ dns_servers = g_array_new (FALSE, FALSE, sizeof (guint)); ++ ++ inet_aton (conf->provider->dns1, &tmp_addr); ++ g_array_append_val (dns_servers, tmp_addr.s_addr); ++ ++ if (conf->provider->dns2) { ++ inet_aton (conf->provider->dns2, &tmp_addr); ++ g_array_append_val (dns_servers, tmp_addr.s_addr); ++ } ++ } ++ ++ /* TODO: gateway */ ++ ++ g_object_set (ipv4conf, ++ NM_SETTING_IP4_CONFIG_METHOD, method, ++ NM_SETTING_IP4_CONFIG_DNS, dns_servers, ++ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns, ++ NULL); ++ ++ nm_connection_add_setting (connection, NM_SETTING (s_gsm)); ++ ++ s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); ++ nm_connection_add_setting (connection, NM_SETTING (s_ppp)); ++ ++ ++ applet->mbca_free_configuration_func (conf); ++ if (dns_servers) ++ g_array_free (dns_servers, TRUE); ++ ++ exported = nma_gconf_settings_add_connection (applet->gconf_settings, connection); ++ if (!exported) { ++ g_object_unref (connection); ++ g_return_if_reached (); ++ } ++ g_object_unref (connection); ++ ++ applet_do_notify (applet, NOTIFY_URGENCY_LOW, ++ _("New Configuration Created"), ++ _("You can activate the connection by clicking this icon.\n" ++ "\n" ++ "Use connection editor to add new and to change settings if necessary"), ++ "nm-device-wwan", NULL, NULL, NULL, NULL); ++ ++ /* FALLTHROUGH */ ++ } ++ case MBCA_STATE_ABORTED: ++ { ++ for (iter = applet->mbca_assistants; iter; iter = iter->next){ ++ if ((MBCAAssistant*)(iter->data) == assistant) { ++ UdiAssistant* ua = iter->data; ++ g_object_unref (G_OBJECT (ua->assistant)); ++ g_free (ua->udi); ++ applet->mbca_assistants = g_slist_remove_all (applet->mbca_assistants, ++ ua); ++ ++ g_free (ua); ++ ++ } ++ } ++ break; ++ } ++ default: ++ { ++ g_return_if_reached (); ++ } ++ } ++ ++} ++#endif ++ ++ + #define DEFAULT_GSM_NAME _("Auto GSM network connection") + + static NMConnection * + gsm_new_auto_connection (NMDevice *device, + NMApplet *applet, + gpointer user_data) + { + NMConnection *connection; + NMSettingGsm *s_gsm; + NMSettingSerial *s_serial; + NMSettingPPP *s_ppp; + NMSettingConnection *s_con; + ++#ifdef WITH_MBCA ++ UdiAssistant* ua; ++ const gchar* udi; ++ GSList* iter; ++ ++ if (applet_open_mbca (applet)) ++ { ++ udi = nm_device_get_udi (device); ++ ++ for (iter = applet->mbca_assistants; iter; iter = iter->next) { ++ UdiAssistant* tmp = iter->data; ++ if (!strcmp (tmp->udi, udi)) ++ { ++ applet->mbca_assistant_present_func (tmp->assistant); ++ break; ++ } ++ } ++ if (!iter) ++ { ++ /* not found */ ++ ua = g_malloc (sizeof (UdiAssistant)); ++ ua->udi = g_strdup (udi); ++ ua->assistant = applet->mbca_assistant_new_func (); ++ g_signal_connect (G_OBJECT (ua->assistant), "state-changed", ++ G_CALLBACK (assistant_state_changed_cb), applet); ++ applet->mbca_assistants = g_slist_prepend (applet->mbca_assistants, ua); ++ applet->mbca_assistant_run_for_device_func (ua->assistant, ++ MBCA_DEVICE_PSEUDO, ++ NULL, NULL); ++ } ++ ++ nm_warning ("There's a new GSM modem being configured and no " ++ "configuration is yet available. You can safely ignore the " ++ "next warninig, if any, about missing default configuration." ++ ); ++ return NULL; ++ } ++ else ++ { ++ /* continue to default code */ ++ } ++#endif ++ + connection = nm_connection_new (); + + s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); + s_gsm->number = g_strdup ("*99#"); /* This should be a sensible default as it's seems to be quite standard */ + nm_connection_add_setting (connection, NM_SETTING (s_gsm)); + + /* Serial setting */ + s_serial = (NMSettingSerial *) nm_setting_serial_new (); +@@ -88,16 +282,18 @@ + s_con->type = g_strdup (NM_SETTING (s_gsm)->name); + s_con->autoconnect = FALSE; + s_con->uuid = nm_utils_uuid_generate (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + return connection; + } + ++ ++ + static void + gsm_menu_item_activate (GtkMenuItem *item, gpointer user_data) + { + GSMMenuItemInfo *info = (GSMMenuItemInfo *) user_data; + + applet_menu_item_activate_helper (info->device, + info->connection, + "/", +@@ -142,19 +338,25 @@ + } + + static void + add_default_connection_item (NMDevice *device, + GtkWidget *menu, + NMApplet *applet) + { + GSMMenuItemInfo *info; +- GtkWidget *item; ++ GtkWidget *item = NULL; ++ ++#ifdef WITH_MBCA ++ if (applet_open_mbca (applet)) ++ item = gtk_check_menu_item_new_with_label (_("Configure...")); ++#endif ++ if (!item) ++ item = gtk_check_menu_item_new_with_label (DEFAULT_GSM_NAME); + +- item = gtk_check_menu_item_new_with_label (DEFAULT_GSM_NAME); + gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), TRUE); + + info = g_slice_new0 (GSMMenuItemInfo); + info->applet = applet; + info->device = g_object_ref (G_OBJECT (device)); + + g_signal_connect_data (item, "activate", + G_CALLBACK (gsm_menu_item_activate), +@@ -298,16 +500,68 @@ + applet_do_notify (applet, NOTIFY_URGENCY_LOW, + _("Connection Established"), + str ? str : _("You are now connected to the GSM network."), + "nm-device-wwan", NULL, NULL, NULL, NULL); + g_free (str); + } + } + ++#ifdef WITH_MBCA ++typedef struct { ++ NMDevice* device; ++ NMApplet* applet; ++} NotifyConfigureNewDeviceCbData; ++ ++static void ++notify_configure_new_device_cb (NotifyNotification* notification, gchar* foo, gpointer data) ++{ ++ NotifyConfigureNewDeviceCbData* d = data; ++ gsm_new_auto_connection (d->device, d->applet, NULL); ++ g_free (d); ++} ++ ++static void ++gsm_device_added (NMDevice *device, NMApplet *applet) ++{ ++ GSList *connections, *all; ++ ++ if (!applet_open_mbca (applet)) ++ return; ++ ++ all = applet_get_all_connections (applet); ++ connections = utils_filter_connections_for_device (device, all); ++ g_slist_free (all); ++ ++ if (g_slist_length (connections) == 0) ++ { ++ gchar* summary; ++ NotifyConfigureNewDeviceCbData* d = g_malloc (sizeof (NotifyConfigureNewDeviceCbData)); ++ d->device = device; ++ d->applet = applet; ++ ++ summary = g_strdup_printf ("%s:\n - %s", ++ utils_get_device_description (device), ++ _("Click here to configure the device...") ++ ); ++ ++ applet_do_notify (applet, NOTIFY_URGENCY_LOW, ++ _("New Mobile Broadband Device Detected"), ++ summary, ++ "nm-device-wwan", ++ "configure", ++ "Configure", ++ notify_configure_new_device_cb, ++ d); ++ g_free (summary); ++ } ++ ++} ++#endif ++ + static GdkPixbuf * + gsm_get_icon (NMDevice *device, + NMDeviceState state, + char **tip, + NMApplet *applet) + { + GdkPixbuf *pixbuf = NULL; + const char *iface; +@@ -618,11 +872,15 @@ + return NULL; + + dclass->new_auto_connection = gsm_new_auto_connection; + dclass->add_menu_item = gsm_add_menu_item; + dclass->device_state_changed = gsm_device_state_changed; + dclass->get_icon = gsm_get_icon; + dclass->get_secrets = gsm_get_secrets; + ++#ifdef WITH_MBCA ++ dclass->device_added = gsm_device_added; ++#endif ++ + return dclass; + } + +Index: network-manager-applet-0.7~~svn20080927t101113/src/applet.c +=================================================================== +--- network-manager-applet-0.7~~svn20080927t101113.orig/src/applet.c ++++ network-manager-applet-0.7~~svn20080927t101113/src/applet.c +@@ -893,16 +893,63 @@ + break; + } + } + } + + return connection; + } + ++#ifdef WITH_MBCA ++gboolean ++applet_open_mbca (NMApplet *applet) ++{ ++ if (applet->mbca_module) ++ return TRUE; ++ ++ applet->mbca_module = g_module_open ("libmbca.so.0", G_MODULE_BIND_LAZY | ++ G_MODULE_BIND_LOCAL); ++ if (!applet->mbca_module) ++ return FALSE; ++ ++ if (!g_module_symbol (applet->mbca_module, ++ "mbca_assistant_abort", ++ ((gpointer)(&applet->mbca_assistant_abort_func)))); ++ g_warn_if_reached (); ++ ++ if (!g_module_symbol (applet->mbca_module, ++ "mbca_assistant_present", ++ (gpointer)(&applet->mbca_assistant_present_func)) ); ++ g_warn_if_reached (); ++ ++ if (!g_module_symbol (applet->mbca_module, ++ "mbca_assistant_new", ++ (gpointer)(&applet->mbca_assistant_new_func))); ++ g_warn_if_reached (); ++ ++ if (!g_module_symbol (applet->mbca_module, ++ "mbca_assistant_run_for_device", ++ (gpointer)(&applet->mbca_assistant_run_for_device_func))); ++ g_warn_if_reached (); ++ ++ if (!g_module_symbol (applet->mbca_module, ++ "mbca_assistant_get_configuration", ++ (gpointer)(&applet->mbca_assistant_get_configuration_func))); ++ g_warn_if_reached (); ++ ++ if (!g_module_symbol (applet->mbca_module, ++ "mbca_free_configuration", ++ (gpointer)(&applet->mbca_free_configuration_func))); ++ g_warn_if_reached (); ++ ++ return TRUE; ++} ++#endif ++ ++ + static guint32 + nma_menu_add_devices (GtkWidget *menu, NMApplet *applet) + { + const GPtrArray *temp = NULL; + GSList *devices = NULL, *iter = NULL; + gint n_wifi_devices = 0; + gint n_usable_wifi_devices = 0; + gint n_wired_devices = 0; +@@ -2253,16 +2300,31 @@ + g_object_unref (applet); + return NULL; + } + + static void finalize (GObject *object) + { + NMApplet *applet = NM_APPLET (object); + ++#ifdef WITH_MBCA ++ GSList* iter = NULL; ++ ++ for (iter = applet->mbca_assistants; iter; iter = iter->next) { ++ UdiAssistant* ua = iter->data; ++ if (!applet_open_mbca (applet)) ++ g_return_if_reached (); /* no assistants without libmbca */ ++ applet->mbca_assistant_abort_func (ua->assistant); ++ /* let the cb handle freeing of resources */ ++ } ++ ++ if (applet->mbca_module) ++ g_module_close (applet->mbca_module); ++#endif ++ + if (applet->update_timestamps_id) + g_source_remove (applet->update_timestamps_id); + + g_slice_free (NMADeviceClass, applet->wired_class); + g_slice_free (NMADeviceClass, applet->wifi_class); + g_slice_free (NMADeviceClass, applet->gsm_class); + + if (applet->update_icon_id) +@@ -2297,16 +2359,21 @@ + + static void nma_init (NMApplet *applet) + { + applet->animation_id = 0; + applet->animation_step = 0; + applet->icon_theme = NULL; + applet->notification = NULL; + applet->size = -1; ++ ++#ifdef WITH_MBCA ++ applet->mbca_assistants = NULL; ++ applet->mbca_module = NULL; ++#endif + } + + static void nma_class_init (NMAppletClass *klass) + { + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->constructor = constructor; + gobject_class->finalize = finalize; +Index: network-manager-applet-0.7~~svn20080927t101113/src/applet.h +=================================================================== +--- network-manager-applet-0.7~~svn20080927t101113.orig/src/applet.h ++++ network-manager-applet-0.7~~svn20080927t101113/src/applet.h +@@ -43,26 +43,38 @@ + #include + #include + #include + #include + #include + #include + #include + ++#ifdef WITH_MBCA ++#include ++#endif ++ + #include "applet-dbus-manager.h" + #include "nma-gconf-settings.h" + + #define NM_TYPE_APPLET (nma_get_type()) + #define NM_APPLET(object) (G_TYPE_CHECK_INSTANCE_CAST((object), NM_TYPE_APPLET, NMApplet)) + #define NM_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_APPLET, NMAppletClass)) + #define NM_IS_APPLET(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), NM_TYPE_APPLET)) + #define NM_IS_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_APPLET)) + #define NM_APPLET_GET_CLASS(object)(G_TYPE_INSTANCE_GET_CLASS((object), NM_TYPE_APPLET, NMAppletClass)) + ++#ifdef WITH_MBCA ++typedef struct ++{ ++ char* udi; ++ MBCAAssistant* assistant; ++} UdiAssistant; ++#endif ++ + typedef struct + { + GObjectClass parent_class; + } NMAppletClass; + + #define APPLET_PREFS_PATH "/apps/nm-applet" + + #define ICON_LAYER_LINK 0 +@@ -135,16 +147,30 @@ + guint networking_enabled_toggled_id; + GtkWidget * wifi_enabled_item; + guint wifi_enabled_toggled_id; + GtkWidget * info_menu_item; + GtkWidget * connections_menu_item; + + GladeXML * info_dialog_xml; + NotifyNotification* notification; ++ ++#ifdef WITH_MBCA ++ GSList *mbca_assistants; /* list of UdiAssistant */ ++ GModule *mbca_module; ++ void (*mbca_assistant_abort_func) (MBCAAssistant*); ++ void (*mbca_assistant_present_func) (MBCAAssistant*); ++ MBCAAssistant* (*mbca_assistant_new_func) (); ++ gint (*mbca_assistant_run_for_device_func) (MBCAAssistant*, ++ MBCADeviceType, ++ const gchar*, ++ const gchar*); ++ MBCAConfiguration* (*mbca_assistant_get_configuration_func) (MBCAAssistant*); ++ void (*mbca_free_configuration_func) (MBCAConfiguration*); ++#endif + } NMApplet; + + + struct NMADeviceClass { + NMConnection * (*new_auto_connection) (NMDevice *device, + NMApplet *applet, + gpointer user_data); + +@@ -209,9 +235,13 @@ + const char *action1_label, + NotifyActionCallback action1_cb, + gpointer action1_user_data); + + NMConnection * applet_find_active_connection_for_device (NMDevice *device, + NMApplet *applet, + NMActiveConnection **out_active); + ++#ifdef WITH_MBCA ++gboolean applet_open_mbca (NMApplet *applet); ++#endif ++ + #endif +Index: network-manager-applet-0.7~~svn20080927t101113/src/connection-editor/nm-connection-list.c +=================================================================== +--- network-manager-applet-0.7~~svn20080927t101113.orig/src/connection-editor/nm-connection-list.c ++++ network-manager-applet-0.7~~svn20080927t101113/src/connection-editor/nm-connection-list.c +@@ -52,16 +52,23 @@ + #include + #include + #include + #include + #include + #include + #include + ++#ifdef WITH_MBCA ++#include ++#include ++#include ++#include ++#endif ++ + #include "nm-connection-editor.h" + #include "nm-connection-list.h" + #include "gconf-helpers.h" + #include "mobile-wizard.h" + #include "utils.h" + #include "vpn-helpers.h" + + G_DEFINE_TYPE (NMConnectionList, nm_connection_list, G_TYPE_OBJECT) +@@ -101,16 +108,52 @@ + GTK_BUTTONS_CLOSE, + "%s", msg); + g_free (msg); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } + ++#ifdef WITH_MBCA ++static gboolean ++open_mbca (NMConnectionList *list) ++{ ++ if (list->mbca_module) ++ return TRUE; ++ ++ list->mbca_module = g_module_open ("libmbca.so.0", G_MODULE_BIND_LAZY | ++ G_MODULE_BIND_LOCAL); ++ if (!list->mbca_module) ++ return FALSE; ++ ++ if (!g_module_symbol (list->mbca_module, ++ "mbca_assistant_new", ++ (gpointer)(&list->mbca_assistant_new_func))); ++ g_warn_if_reached (); ++ ++ if (!g_module_symbol (list->mbca_module, ++ "mbca_assistant_run_for_device", ++ (gpointer)(&list->mbca_assistant_run_for_device_func))); ++ g_warn_if_reached (); ++ ++ if (!g_module_symbol (list->mbca_module, ++ "mbca_assistant_get_configuration", ++ (gpointer)(&list->mbca_assistant_get_configuration_func))); ++ g_warn_if_reached (); ++ ++ if (!g_module_symbol (list->mbca_module, ++ "mbca_free_configuration", ++ (gpointer)(&list->mbca_free_configuration_func))); ++ g_warn_if_reached (); ++ ++ return TRUE; ++} ++#endif ++ + static NMExportedConnection * + get_active_connection (GtkTreeView *treeview) + { + GtkTreeSelection *selection; + GList *selected_rows; + GtkTreeModel *model = NULL; + GtkTreeIter iter; + NMExportedConnection *exported = NULL; +@@ -765,24 +808,151 @@ + s_serial = NM_SETTING_SERIAL (nm_setting_serial_new ()); + s_serial->baud = 115200; + s_serial->bits = 8; + s_serial->parity = 'n'; + s_serial->stopbits = 1; + nm_connection_add_setting (connection, NM_SETTING (s_serial)); + } + ++#ifdef WITH_MBCA ++static void ++mbca_assistant_state_changed_cb (MBCAAssistant* assistant, ++ MBCAAssistantState state, ++ gpointer user_data) ++{ ++ NMConnection *connection = NULL; ++ NMSettingConnection *s_con; ++ NMSetting *type_setting = NULL; ++ MBCAConfiguration* conf; ++ ++ NMConnectionList *list = user_data; ++ ++ NMSettingIP4Config* ipv4conf; ++ gboolean ignore_auto_dns = FALSE; ++ GArray *dns_servers = FALSE; ++ const char *method; ++ ++ switch (state) { ++ case MBCA_STATE_READY: ++ case MBCA_STATE_RUNNING: ++ return; ++ case MBCA_STATE_DONE: ++ ++ /* this function should never get called without a prior usage of ++ * libmbca in create_new_connection_for_type ++ */ ++ g_return_if_fail (open_mbca (list)); ++ ++ connection = nm_connection_new (); ++ nm_connection_set_scope (connection, NM_CONNECTION_SCOPE_USER); ++ ++ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); ++ nm_connection_add_setting (connection, NM_SETTING (s_con)); ++ ++ ipv4conf = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); ++ nm_connection_add_setting (connection, NM_SETTING (ipv4conf)); ++ ++ conf = list->mbca_assistant_get_configuration_func (assistant); ++ ++ s_con->id = g_strdup (conf->name); ++ s_con->uuid = nm_utils_uuid_generate (); ++ s_con->autoconnect = FALSE; ++ ++ add_default_serial_setting (connection); ++ ++ method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; ++ ++ if (conf->provider->type == MBCA_NETWORK_GSM) { ++ NMSettingGsm *s_gsm; ++ ++ s_con->type = g_strdup (NM_SETTING_GSM_SETTING_NAME); ++ ++ type_setting = nm_setting_gsm_new (); ++ s_gsm = NM_SETTING_GSM (type_setting); ++ s_gsm->number = g_strdup ("*99#"); /* De-facto standard for GSM */ ++ ++ s_gsm->apn = g_strdup (conf->provider->gsm.apn); ++ ++ s_gsm->username = g_strdup (conf->provider->username); ++ s_gsm->password = g_strdup (conf->provider->password); ++ ++ ++ if (conf->provider->dns1) { ++ struct in_addr tmp_addr; ++ ignore_auto_dns = TRUE; ++ dns_servers = g_array_new (FALSE, FALSE, sizeof (guint)); ++ ++ inet_aton (conf->provider->dns1, &tmp_addr); ++ g_array_append_val (dns_servers, tmp_addr.s_addr); ++ ++ if (conf->provider->dns2) { ++ inet_aton (conf->provider->dns2, &tmp_addr); ++ g_array_append_val (dns_servers, tmp_addr.s_addr); ++ } ++ } ++ ++ /* TODO: gateway */ ++ ++ } else if (conf->provider->type == MBCA_NETWORK_CDMA) { ++ NMSettingCdma *s_cdma; ++ ++ s_con->type = g_strdup (NM_SETTING_CDMA_SETTING_NAME); ++ ++ type_setting = nm_setting_cdma_new (); ++ s_cdma = NM_SETTING_CDMA (type_setting); ++ s_cdma->number = g_strdup ("#777"); /* De-facto standard for CDMA */ ++ ++ s_cdma->username = g_strdup (conf->provider->username); ++ s_cdma->password = g_strdup (conf->provider->password); ++ } ++ nm_connection_add_setting (connection, nm_setting_ppp_new ()); ++ ++ g_object_set (ipv4conf, ++ NM_SETTING_IP4_CONFIG_METHOD, method, ++ NM_SETTING_IP4_CONFIG_DNS, dns_servers, ++ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns, ++ NULL); ++ ++ if (type_setting) { ++ nm_connection_add_setting (connection, type_setting); ++ } else { ++ g_object_unref (connection); ++ connection = NULL; ++ } ++ ++ add_connection (list, NULL, connection, NULL, NULL); ++ g_hash_table_remove (list->editors, connection); ++ ++ list->mbca_free_configuration_func (conf); ++ if (dns_servers) ++ g_array_free (dns_servers, TRUE); ++ /* FALLTHROUGH */ ++ ++ case MBCA_STATE_ABORTED: ++ g_object_unref (assistant); ++ break; ++ default: ++ g_warn_if_reached (); ++ } ++} ++#endif ++ + static NMConnection * + create_new_connection_for_type (NMConnectionList *list, const char *connection_type) + { + GType ctype; + NMConnection *connection = NULL; + NMSettingConnection *s_con; + NMSetting *type_setting = NULL; + GType mb_type; ++#ifdef WITH_MBCA ++ MBCAAssistant *assistant = NULL; ++#endif ++ gboolean use_mbca = FALSE; + + ctype = nm_connection_lookup_setting_type (connection_type); + + connection = nm_connection_new (); + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + s_con->uuid = nm_utils_uuid_generate (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + +@@ -798,51 +968,76 @@ + s_con->id = get_next_available_name (list, _("Wireless connection %d")); + s_con->type = g_strdup (NM_SETTING_WIRELESS_SETTING_NAME); + s_con->autoconnect = TRUE; + + type_setting = nm_setting_wireless_new (); + s_wireless = NM_SETTING_WIRELESS (type_setting); + s_wireless->mode = g_strdup ("infrastructure"); + } else if ((ctype == NM_TYPE_SETTING_GSM) || (ctype == NM_TYPE_SETTING_CDMA)) { +- /* Since GSM is a placeholder for both GSM and CDMA; ask the user which +- * one they really want. +- */ +- mb_type = mobile_wizard_ask_connection_type (); +- if (mb_type == NM_TYPE_SETTING_GSM) { +- NMSettingGsm *s_gsm; +- +- s_con->id = get_next_available_name (list, _("GSM connection %d")); +- s_con->type = g_strdup (NM_SETTING_GSM_SETTING_NAME); +- s_con->autoconnect = FALSE; +- +- add_default_serial_setting (connection); +- +- type_setting = nm_setting_gsm_new (); +- s_gsm = NM_SETTING_GSM (type_setting); +- s_gsm->number = g_strdup ("*99#"); /* De-facto standard for GSM */ +- +- nm_connection_add_setting (connection, nm_setting_ppp_new ()); +- } else if (mb_type == NM_TYPE_SETTING_CDMA) { +- NMSettingCdma *s_cdma; +- +- s_con->id = get_next_available_name (list, _("CDMA connection %d")); +- s_con->type = g_strdup (NM_SETTING_CDMA_SETTING_NAME); +- s_con->autoconnect = FALSE; + +- add_default_serial_setting (connection); +- +- type_setting = nm_setting_cdma_new (); +- s_cdma = NM_SETTING_CDMA (type_setting); +- s_cdma->number = g_strdup ("#777"); /* De-facto standard for CDMA */ ++#ifdef WITH_MBCA ++ use_mbca = open_mbca (list); ++#endif ++ if (use_mbca) ++ { ++#ifdef WITH_MBCA ++ ++ assistant = list->mbca_assistant_new_func (); ++ g_signal_connect (G_OBJECT (assistant), "state-changed", ++ G_CALLBACK (mbca_assistant_state_changed_cb), list); ++ list->mbca_assistant_run_for_device_func (assistant, ++ MBCA_DEVICE_PSEUDO, ++ NULL, NULL); ++ ++ mb_type = NM_TYPE_SETTING_GSM; /* get rid of compiler warning about ++ * unused variable */ ++#endif ++ } ++ else ++ { ++ /* MBCA support not compiled in or libmbca is missing */ + +- nm_connection_add_setting (connection, nm_setting_ppp_new ()); +- } else { +- /* user canceled; do nothing */ ++ /* Since GSM is a placeholder for both GSM and CDMA; ask the user which ++ * one they really want. ++ */ ++ mb_type = mobile_wizard_ask_connection_type (); ++ if (mb_type == NM_TYPE_SETTING_GSM) { ++ NMSettingGsm *s_gsm; ++ ++ s_con->id = get_next_available_name (list, _("GSM connection %d")); ++ s_con->type = g_strdup (NM_SETTING_GSM_SETTING_NAME); ++ s_con->autoconnect = FALSE; ++ ++ add_default_serial_setting (connection); ++ ++ type_setting = nm_setting_gsm_new (); ++ s_gsm = NM_SETTING_GSM (type_setting); ++ s_gsm->number = g_strdup ("*99#"); /* De-facto standard for GSM */ ++ ++ nm_connection_add_setting (connection, nm_setting_ppp_new ()); ++ } else if (mb_type == NM_TYPE_SETTING_CDMA) { ++ NMSettingCdma *s_cdma; ++ ++ s_con->id = get_next_available_name (list, _("CDMA connection %d")); ++ s_con->type = g_strdup (NM_SETTING_CDMA_SETTING_NAME); ++ s_con->autoconnect = FALSE; ++ ++ add_default_serial_setting (connection); ++ ++ type_setting = nm_setting_cdma_new (); ++ s_cdma = NM_SETTING_CDMA (type_setting); ++ s_cdma->number = g_strdup ("#777"); /* De-facto standard for CDMA */ ++ ++ nm_connection_add_setting (connection, nm_setting_ppp_new ()); ++ } else { ++ /* user canceled; do nothing */ ++ } + } ++ + } else if (ctype == NM_TYPE_SETTING_VPN) { + char *service = NULL; + + service = vpn_ask_connection_type (); + if (service) { + NMSettingVPN *s_vpn; + + s_con->id = get_next_available_name (list, _("VPN connection %d")); +@@ -1206,16 +1401,20 @@ + { + gtk_widget_hide (GTK_WIDGET (dialog)); + } + + static void + nm_connection_list_init (NMConnectionList *list) + { + list->treeviews = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ++ ++#ifdef WITH_MBCA ++ list->mbca_module = NULL; ++#endif + } + + static void + dispose (GObject *object) + { + NMConnectionList *list = NM_CONNECTION_LIST (object); + + if (list->dialog) +@@ -1245,16 +1444,21 @@ + g_hash_table_destroy (list->treeviews); + + if (list->gconf_settings) + g_object_unref (list->gconf_settings); + + if (list->system_settings) + g_object_unref (list->system_settings); + ++#if WITH_MBCA ++ if (list->mbca_module) ++ g_module_close (list->mbca_module); ++#endif ++ + G_OBJECT_CLASS (nm_connection_list_parent_class)->dispose (object); + } + + static void + nm_connection_list_class_init (NMConnectionListClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + +Index: network-manager-applet-0.7~~svn20080927t101113/src/connection-editor/nm-connection-list.h +=================================================================== +--- network-manager-applet-0.7~~svn20080927t101113.orig/src/connection-editor/nm-connection-list.h ++++ network-manager-applet-0.7~~svn20080927t101113/src/connection-editor/nm-connection-list.h +@@ -27,16 +27,20 @@ + #include + #include + #include + #include + #include + #include + #include "nma-gconf-settings.h" + ++#ifdef WITH_MBCA ++#include ++#endif ++ + #define NM_TYPE_CONNECTION_LIST (nm_connection_list_get_type ()) + #define NM_IS_CONNECTION_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION_LIST)) + #define NM_CONNECTION_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION_LIST, NMConnectionList)) + + typedef struct { + GObject parent; + + /* private data */ +@@ -51,16 +55,26 @@ + GtkWidget *dialog; + + GdkPixbuf *wired_icon; + GdkPixbuf *wireless_icon; + GdkPixbuf *wwan_icon; + GdkPixbuf *vpn_icon; + GdkPixbuf *unknown_icon; + GtkIconTheme *icon_theme; ++#ifdef WITH_MBCA ++ GModule *mbca_module; ++ MBCAAssistant* (*mbca_assistant_new_func) (); ++ gint (*mbca_assistant_run_for_device_func) (MBCAAssistant*, ++ MBCADeviceType, ++ const gchar*, ++ const gchar*); ++ MBCAConfiguration* (*mbca_assistant_get_configuration_func) (MBCAAssistant*); ++ void (*mbca_free_configuration_func) (MBCAConfiguration*); ++#endif + } NMConnectionList; + + typedef struct { + GObjectClass parent_class; + + /* Signals */ + void (*done) (NMConnectionList *list, gint result); + } NMConnectionListClass; +Index: network-manager-applet-0.7~~svn20080927t101113/src/connection-editor/nm-connection-editor.c +=================================================================== +--- network-manager-applet-0.7~~svn20080927t101113.orig/src/connection-editor/nm-connection-editor.c ++++ network-manager-applet-0.7~~svn20080927t101113/src/connection-editor/nm-connection-editor.c +@@ -351,16 +351,17 @@ + } else if (!strcmp (s_con->type, NM_SETTING_PPPOE_SETTING_NAME)) { + add_page (editor, CE_PAGE (ce_page_dsl_new (editor->connection))); + add_page (editor, CE_PAGE (ce_page_wired_new (editor->connection))); + add_page (editor, CE_PAGE (ce_page_ppp_new (editor->connection))); + } else if (!strcmp (s_con->type, NM_SETTING_GSM_SETTING_NAME) || + !strcmp (s_con->type, NM_SETTING_CDMA_SETTING_NAME)) { + add_page (editor, CE_PAGE (ce_page_mobile_new (editor->connection))); + add_page (editor, CE_PAGE (ce_page_ppp_new (editor->connection))); ++ add_page (editor, CE_PAGE (ce_page_ip4_new (editor->connection))); + } else { + g_warning ("Unhandled setting type '%s'", s_con->type); + } + + /* set the UI */ + populate_connection_ui (editor); + + connection_editor_validate (editor); +Index: network-manager-applet-0.7~~svn20080927t101113/configure.ac +=================================================================== +--- network-manager-applet-0.7~~svn20080927t101113.orig/configure.ac ++++ network-manager-applet-0.7~~svn20080927t101113/configure.ac +@@ -208,16 +208,26 @@ + unset has_option + unset SAVE_CFLAGS + done + unset option + else + AC_MSG_RESULT(no) + fi + ++AC_ARG_WITH(mbca, AC_HELP_STRING([--with-mbca], [use Mobile Broadband Configuration Assistant])) ++ ++if ! test -z "$with_mbca" ; then ++ CFLAGS="$CFLAGS -DWITH_MBCA" ++ PKG_CHECK_MODULES(MBCA, libmbca) ++ NMA_CFLAGS="$NMA_CFLAGS $MBCA_CFLAGS" ++ #NMA_LIBS="$NMA_LIBS $MBCA_LIBS" ++fi ++ ++ + AC_OUTPUT([ + Makefile + src/Makefile + src/marshallers/Makefile + src/utils/Makefile + src/gconf-helpers/Makefile + src/wireless-security/Makefile + src/connection-editor/Makefile --- network-manager-applet-0.7~~svn20081005t082522.orig/debian/patches/20_use_full_vpn_dialog_service_name_path.patch +++ network-manager-applet-0.7~~svn20081005t082522/debian/patches/20_use_full_vpn_dialog_service_name_path.patch @@ -0,0 +1,59 @@ + +We dont want LIBEXECDIR shuffeling. The vpn daemon building system knows +better where the auth-dialog will be installed to; thus we just use the +full path stored in VPN/*.name files. + +-- + +=== modified file 'src/vpn-password-dialog.c' +--- a/src/vpn-password-dialog.c 2008-07-03 12:55:56 +0000 ++++ b/src/vpn-password-dialog.c 2008-08-14 22:51:24 +0000 +@@ -136,26 +136,16 @@ out: + GTK_BUTTONS_CLOSE, + _("Cannot start VPN connection '%s'"), + name); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("Could not find the authentication dialog for VPN connection type '%s'. Contact your system administrator."), + service); + gtk_window_present (GTK_WINDOW (dialog)); + g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog); +- } else { +- char *basename; +- +- /* Remove any path component, then reconstruct path to the auth +- * dialog in LIBEXECDIR. +- */ +- basename = g_path_get_basename (prog); +- g_free (prog); +- prog = g_strdup_printf ("%s/%s", LIBEXECDIR, basename); +- g_free (basename); + } + + return prog; + } + + static void + destroy_gvalue (gpointer data) + { +@@ -245,18 +235,18 @@ nma_vpn_request_password (NMExportedConn + _("Cannot start VPN connection '%s'"), + s_con->id); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("There was a problem launching the authentication dialog for VPN connection type '%s'. Contact your system administrator."), + s_vpn->service_type); + gtk_window_present (GTK_WINDOW (dialog)); + g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog); + g_set_error (&error, NM_SETTINGS_ERROR, 1, +- "%s.%d (%s): couldn't run VPN auth dialog.", +- __FILE__, __LINE__, __func__); ++ "%s.%d (%s): couldn't run VPN auth dialog (cmd=%s).", ++ __FILE__, __LINE__, __func__, argv[0]); + goto out; + } + + /* catch when child is reaped */ + g_child_watch_add (child_pid, child_finished_cb, (gpointer) &child_status); + + io_user_data.lines = NULL; + io_user_data.child_stdin = child_stdin; +