Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
Net/XWhois.pm000066600000113416150777111550007074 0ustar00#!/usr/bin/perl ## ## Net::XWhois ## Whois Client Interface Class. ## ## $Date: 2001/07/14 07:25:31 $ ## $Revision: 1.3 $ ## $State: Exp $ ## $Author: vipul $ ## ## Copyright (c) 1998, Vipul Ved Prakash. All rights reserved. ## This code is free software; you can redistribute it and/or modify ## it under the same terms as Perl itself. # # modified August 2002 by Rob Woodard # # Changes: # # 08/05/2002 rwoodard Merged in changes from XWhois discussion forum on # sourceforge.net; made additional changes as needed # to implement reverse lookups of IP addresses # 08/06/2002 rwoodard Added comments for internal documentation. Added # parser defs for ARIN, set APNIC and RIPE to use RPSL. # 08/07/2002 rwoodard Added ARIN-specific following of multiple netblocks; # this is done by setting the Bottom_netblock attrib # 08/08/2002 rwoodard Added Verbose attribute for displaying status info # 08/26/2002 rwoodard Revised ARIN parser to reflect updated responses # package Net::XWhois; use Data::Dumper; use IO::Socket; use Carp; use vars qw ( $VERSION $AUTOLOAD ); $VERSION = '0.90'; my $CACHE = "/tmp/whois"; my $EXPIRE = 604800; my $ERROR = "return"; my $TIMEOUT = 20; my $RETRIES = 3; my %PARSERS = ( #these are the parser definitions for each whois server. #the AUTOLOAD subroutine creates an object method for each key defined within #the server's hash of regexps; this applies the regexp to the response from #the whois server to extract the data. of course you can just write your own #parsing subroutine as described in the docs. # #there ought to be some standardization of the fields being parsed. for my #own personal purposes only RPSL and ARIN are standardized; there needs to be #some work done on the other defs to get them to return at least these fields: # # name name of registrant entity (company or person) # netname name assigned to registrant's network # inetnum address range registered # abuse_email email addresses named 'abuse@yaddayadda' # gen_email general correspondence email addresses # #yes some of these are redundant to what is already there; I saw no reason to #delete non-standardized keys, they don't take that much space and might be #needed for backwards compatibility. -rwoodard 08/2002 RPSL => { #updated by rwoodard 08/06/2002 name => '(?:descr|owner):\s+([^\n]*)\n', netname => 'netname:\s+([^\n]*)\n', inetnum => 'inetnum:\s+([^\n]*)\n', abuse_email => '\b(?:abuse|security)\@\S+', gen_email => 'e-*mail:\s+(\S+\@\S+)', country => 'country:\s+(\S+)', status => 'status:\s+([^\n]*)\n', contact_admin => '(?:admin|owner)-c:\s+([^\n]*)\n', contact_tech => 'tech-c:\s+([^\n]*)\n', contact_emails => 'email:\s+(\S+\@\S+)', contact_handles => 'nic-hdl(?:-\S*):\s+([^\n]*)\n', remarks => 'remarks:\s+([^\n]*)\n', notify => 'notify:\s+([^\n]*)\n', forwardwhois => 'remarks:\s+[^\n]*(whois.\w+.\w+)', }, ARIN => { #from Jon Gilbert 09/04/2000 updated/added to by rwoodard 08/07/2002 name => '(?:OrgName|CustName):\s*(.*?)\n', netname => 'etName:\s*(\S+)\n+', inetnum => 'etRange:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} - \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})[\n\s]*', abuse_email => '(?:abuse|security)\@\S+', gen_email => 'Coordinator:[\n\s]+.*?(\S+\@\S+)', netnum => 'Netnumber:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})[\n\s]*', hostname => 'Hostname:\s*(\S+)[\n\s]*', maintainer => 'Maintainer:\s*(\S+)', #record_update => 'Record last updated on (\S+)\.\n+', record_update => 'Updated:(\S+)\n+', database_update => 'Database last updated on (.+)\.[\n\s]+The', registrant => '^(.*?)\n\n', reverse_mapping => 'Domain System inverse[\s\w]+:[\n\s]+(.*?)\n\n', coordinator => 'Coordinator:[\n\s]+(.*?)\n\n', coordinator_handle => 'Coordinator:[\n\s]+[^\(\)]+\((\S+?)\)', coordinator_email => 'Coordinator:[\n\s]+.*?(\S+\@\S+)', address => 'Address:\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', system => 'System:\s+([^\n]*)\n', non_portable => 'ADDRESSES WITHIN THIS BLOCK ARE NON-PORTABLE', #multiple => 'To single out one record', multiple => '\((NET\S+)\)', net_handle => '(NET\S+)\)', country => 'Country:\s*(\S+)\n+', }, BRNIC => { name => '(?:descr|owner):\s+([^\n]*)\n', netname => 'netname:\s+([^\n]*)\n', inetnum => 'inetnum:\s+([^\n]*)\n', abuse_email => '\b(?:abuse|security)\@\S+', gen_email => 'e-*mail:\s+(\S+\@\S+)', country => 'BR', #yes this is ugly, tell BRNIC to start putting country fields in their responses status => 'status:\s+([^\n]*)\n', contact_admin => '(?:admin|owner)-c:\s+([^\n]*)\n', contact_tech => 'tech-c:\s+([^\n]*)\n', contact_emails => 'email:\s+(\S+\@\S+)', contact_handles => 'nic-hdl(?:-\S*):\s+([^\n]*)\n', remarks => 'remarks:\s+([^\n]*)\n', notify => 'notify:\s+([^\n]*)\n', forwardwhois => 'remarks:\s+[^\n]*(whois.\w+.\w+)', }, KRNIC => { #added by rwoodard 08/06/2002 }, TWNIC => { #added by rwoodard 08/06/2002 name => '^([^\n]*)\n', netname => 'etname:\s*(\S+)\n+', inetnum => 'etblock:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} - \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})[\n\s]*', abuse_email => '(?:abuse|security)\@\S+', gen_email => 'Coordinator:[\n\s]+.*?(\S+\@\S+)', netnum => 'Netnumber:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})[\n\s]*', hostname => 'Hostname:\s*(\S+)[\n\s]*', maintainer => 'Maintainer:\s*(\S+)', record_update => 'Record last updated on (\S+)\.\n+', database_update => 'Database last updated on (.+)\.[\n\s]+The', registrant => '^(.*?)\n\n', reverse_mapping => 'Domain System inverse[\s\w]+:[\n\s]+(.*?)\n\n', coordinator => 'Coordinator:[\n\s]+(.*?)\n\n', coordinator_handle => 'Coordinator:[\n\s]+[^\(\)]+\((\S+?)\)', coordinator_email => 'Coordinator:[\n\s]+.*?(\S+\@\S+)', address => 'Address:\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', system => 'System:\s+([^\n]*)\n', non_portable => 'ADDRESSES WITHIN THIS BLOCK ARE NON-PORTABLE', multiple => 'To single out one record', net_handle => '\((NETBLK\S+)\)', country => '\n\s+(\S+)\n\n', }, INTERNIC => { name => '[\n\r\f]+\s*[Dd]omain [Nn]ame[:\.]*\s+(\S+)', status => 'omain Status[:\.]+\s+(.*?)\s*\n', nameservers => '[\n\r\f]+\s*([a-zA-Z0-9\-\.]+\.[a-zA-Z0-9\-]+\.[a-zA-Z\-]+)[:\s\n$]', registrant => '(?:egistrant|rgani[sz]ation)[:\.]*\s*\n(.*?)\n\n', contact_admin => '(?:dministrative Contact|dmin Contact).*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_tech => '(?:echnical Contact|ech Contact).*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_zone => 'one Contact.*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_billing => 'illing Contact.*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_emails => '(\S+\@\S+)', contact_handles => '\(([^\W\d]+\d+)\)', domain_handles => '\((\S*?-DOM)\)', org_handles => '\((\S*?-ORG)\)', not_registered => 'No match', forwardwhois => 'Whois Server: (.*?)(?=\n)', }, BULKREG => { name => 'omain Name[:\.]*\s+(\S+)', status => 'omain Status[:\.]+\s+(.*?)\s*\n', nameservers => '[\n\r\f]+\s*([a-zA-Z0-9\-\.]+\.[a-zA-Z0-9\-]+\.[a-zA-Z\-]+)[:\s\n$]', registrant => '(.+)\([\w\-]+\-DOM\).*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_admin => 'dmin[a-zA-Z]*? Contact.*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_tech => 'ech[a-zA-Z]*? Contact.*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_zone => 'one Contact.*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_billing => 'illing Contact.*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_emails => '(\S+\@\S+)', contact_handles => '\((\w+\d+\-BR)\)', domain_handles => '\((\S*?-DOM)\)', org_handles => '\((\S*?-ORG)\)', not_registered => 'Not found\!', forwardwhois => 'Whois Server: (.*?)(?=\n)', registrar => 'egistrar\s*\w*[\.\:]* (.*?)\.?\n', reg_date => 'reated on[\.\:]* (.*?)\.?\n', exp_date => 'xpires on[\.\:]* (.*?)\.?\n', }, INWW => { name => 'omain Name\.+ (\S+)', status => 'omain Status\.+ ([^\n]*)\n', nameservers => 'Name Server\.+ (\S+)', registrant => 'Organisation \w{4,7}\.+ ([^\n]+?)\n', contact_admin => 'Admin \w{3,7}\.+ ([^\n]*)\n', contact_tech => 'Tech \w{3,7}\.+ ([^\n]*)\n', contact_zone => 'Zone \w{3,7}\.+ ([^\n]*)\n', contact_billing => 'Billing \w{3,7}\.+ ([^\n]*)\n', contact_emails => '(\S+\@\S+)', contact_handles => '\((\w+\d+)\)', domain_handles => '\((\S*?-DOM)\)', org_handles => '\((\S*?-ORG)\)', not_registered => 'is not registered', forwardwhois => 'Whois Server: (.*?)(?=\n)', registrar => 'egistrar\s*\w*[\.\:]* (.*?)\.?\n', exp_date => 'Expiry Date\.+ ([^\n]*)\n', reg_date => 'Registration Date\.+ ([^\n]*)\n', }, INTERNIC_CONTACT => { name => '(.+?)\s+\(.*?\)(?:.*?\@)', address => '\n(.*?)\n[^\n]*?\n\n\s+Re', email => '\s+\(.*?\)\s+(\S+\@\S+)', phone => '\n([^\n]*?)\(F[^\n]+\n\n\s+Re', fax => '\(FAX\)\s+([^\n]+)\n\n\s+Re', }, CANADA => { name => 'domain:\s+(\S+)\n', nameservers => '-Netaddress:\s+(\S+)', contact_emails => '-Mailbox:\s+(\S+\@\S+)', }, RIPE => { name => 'domain:\s+(\S+)\n', nameservers => 'nserver:\s+(\S+)', contact_emails => 'e-mail:\s+(\S+\@\S+)', registrant => 'descr:\s+(.+?)\n', }, RIPE_CH => { name => 'Domain Name:[\s\n]+(\S+)\n', nameservers => 'Name servers:[\s\n]+(\S+)[\s\n]+(\S+)', }, NOMINET => { name => 'omain Name:\s+(\S+)', registrant => 'egistered For:\s*(.*?)\n', ips_tag => 'omain Registered By:\s*(.*?)\n', record_updated_date => 'Record last updated on\s*(.*?)\s+', record_updated_by => 'Record last updated on\s*.*?\s+by\s+(.*?)\n', nameservers => 'listed in order:[\s\n]+(\S+)\s.*?\n\s+(\S*?)\s.*?\n\s*\n', whois_updated => 'database last updated at\s*(.*?)\n', }, UKERNA => { name => 'omain Name:\s+(\S+)', registrant => 'egistered For:\s*(.*?)\n', ips_tag => 'omain Registered By:\s*(.*?)\n', record_updated_date => 'ecord updated on\s*(.*?)\s+', record_updated_by => 'ecord updated on\s*.*?\s+by\s+(.*?)\n', nameservers => 'elegated Name Servers:[\s\n]+(\S+)[\s\n]+(\S+).*?\n\s*\n', contact_emails => 'Domain contact:\s*(.*?)\n', }, CENTRALNIC => { name => 'omain Name:\s+(\S+)', registrant => 'egistrant:\s*(.*?)\n', contact_admin => 'lient Contact:\s*(.*?)\n\s*\n', contact_billing => 'illing Contact:\s*(.*?)\n\s*\n', contact_tech => 'echnical Contact:\s*(.*?)\n\s*\n', record_created_date => 'ecord created on\s*(.*?)\n', record_paid_date => 'ecord paid up to\s*(.*?)\n', record_updated_date => 'ecord last updated on\s*(.*?)\n', nameservers => 'in listed order:[\s\n]+(\S+)\s.*?\n\s+(\S*?)\s.*?\n\s*\n', contact_emails => '(\S+\@\S+)', }, DENIC => { name => 'domain:\s+(\S+)\n', registrants => 'descr:\s+(.+?)\n', contact_admin => 'admin-c:\s+(.*?)\s*\n', contact_tech => 'tech-c:\s+(.*?)\s*\n', contact_zone => 'zone-c:\s+(.*?)\s*\n', nameservers => 'nserver:\s+(\S+)', status => 'status:\s+(.*?)\s*\n', changed => 'changed:\s+(.*?)\s*\n', source => 'source:\s+(.*?)\s*\n', person => 'person:\s+(.*?)\s*\n', address => 'address:\s+(.+?)\n', phone => 'phone:\s+(.+?)\n', fax_no => 'fax-no:\s+(.+?)\n', contact_emails => 'e-mail:\s+(.+?)\n', }, JAPAN => { name => '\[Domain Name\]\s+(\S+)', nameservers => 'Name Server\]\s+(\S+)', contact_emails => '\[Reply Mail\]\s+(\S+\@\S+)', }, TAIWAN => { name => 'omain Name:\s+(\S+)', registrant => '^(\S+) \(\S+?DOM)', contact_emails => '(\S+\@\S+)', nameservers => 'servers in listed order:[\s\n]+\%see\-also\s+\.(\S+?)\:', }, KOREA => { name => 'Domain Name\s+:\s+(\S+)', nameservers => 'Host Name\s+:\s+(\S+)', contact_emails => 'E\-Mail\s+:\s*(\S+\@\S+)', }, MEXICO => { name => '[\n\r\f]+\s*[Nn]ombre del [Dd]ominio[:\.]*\s+(\S+)', status => 'omain Status[:\.]+\s+(.*?)\s*\n', nameservers => 'ameserver[^:]*:\s*([a-zA-Z0-9.\-])+', registrant => '(?:egistrant|rgani[sz]acion)[:\.]*\s*\n(.*?)\n\n', contact_admin => '(?:tacto [Aa]dministrativo|dmin Contact).*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_tech => '(?:tacto [Tt]ecnico|ech Contact).*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_billing => 'to de Pago.*?\n(.*?)(?=\s*\n[^\n]+?:\s*\n|[\n\r\f]{2})', contact_emails => '(\S+\@\S+)', contact_handles => '\(([^\W\d]+\d+)\)', not_registered => 'No Encontrado', reg_date => 'de creacion[\.\:]* (.*?)\.?\n', record_updated_date => 'a modificacion[\.\:]* (.*?)\.?\n', }, ADAMS => { name => '(\S+) is \S*\s*registered', not_registered => 'is not registered', }, GENERIC => { contact_emails => '(\S+\@\S+)', }, ); my %WHOIS_PARSER = ( 'whois.ripe.net' => 'RPSL', 'whois.nic.mil' => 'INTERNIC', 'whois.nic.ad.jp' => 'JAPAN', 'whois.domainz.net.nz' => 'GENERIC', 'whois.nic.gov' => 'INTERNIC', 'whois.nic.ch' => 'RIPE_CH', 'whois.twnic.net' => 'TWNIC', 'whois.internic.net' => 'INTERNIC', 'whois.aunic.net' => 'RIPE', 'whois.cdnnet.ca' => 'CANADA', 'whois.ja.net' => 'UKERNA', 'whois.nic.uk' => 'NOMINET', 'whois.krnic.net' => 'KOREA', 'whois.isi.edu' => 'INTERNIC', 'whois.norid.no' => 'RPSL', 'whois.centralnic.com' => 'CENTRALNIC', 'whois.denic.de' => 'DENIC', 'whois.InternetNamesWW.com' => 'INWW', 'whois.bulkregister.com' => 'BULKREG', 'whois.arin.net' => 'ARIN', #added 08/06/2002 by rwoodard 'whois.apnic.net' => 'RPSL', #added 08/06/2002 by rwoodard 'whois.nic.fr' => 'RPSL', 'whois.lacnic.net' => 'RPSL', 'whois.nic.br' => 'BRNIC', 'whois.nic.mx' => 'MEXICO', 'whois.adamsnames.tc' => 'ADAMS', ); my %DOMAIN_ASSOC = ( 'al' => 'whois.ripe.net', 'am' => 'whois.ripe.net', 'at' => 'whois.ripe.net', 'au' => 'whois.aunic.net', 'az' => 'whois.ripe.net', 'ba' => 'whois.ripe.net', 'be' => 'whois.ripe.net', 'bg' => 'whois.ripe.net', 'by' => 'whois.ripe.net', 'ca' => 'whois.cdnnet.ca', 'ch' => 'whois.nic.ch', 'com' => 'whois.internic.net', 'cy' => 'whois.ripe.net', 'cz' => 'whois.ripe.net', 'de' => 'whois.denic.de', 'dk' => 'whois.dk-hostmaster.dk', 'dz' => 'whois.ripe.net', 'edu' => 'whois.internic.net', 'ee' => 'whois.ripe.net', 'eg' => 'whois.ripe.net', 'es' => 'whois.ripe.net', 'fi' => 'whois.ripe.net', 'fo' => 'whois.ripe.net', 'fr' => 'whois.nic.fr', 'gb' => 'whois.ripe.net', 'ge' => 'whois.ripe.net', 'gov' => 'whois.nic.gov', 'gr' => 'whois.ripe.net', 'hr' => 'whois.ripe.net', 'hu' => 'whois.ripe.net', 'ie' => 'whois.ripe.net', 'il' => 'whois.ripe.net', 'is' => 'whois.ripe.net', 'it' => 'whois.ripe.net', 'jp' => 'whois.nic.ad.jp', 'kr' => 'whois.krnic.net', 'li' => 'whois.ripe.net', 'lt' => 'whois.ripe.net', 'lu' => 'whois.ripe.net', 'lv' => 'whois.ripe.net', 'ma' => 'whois.ripe.net', 'md' => 'whois.ripe.net', 'mil' => 'whois.nic.mil', 'mk' => 'whois.ripe.net', 'mt' => 'whois.ripe.net', 'mx' => 'whois.nic.mx', 'net' => 'whois.internic.net', 'nl' => 'whois.ripe.net', 'no' => 'whois.norid.no', 'nz' => 'whois.domainz.net.nz', 'org' => 'whois.internic.net', 'pl' => 'whois.ripe.net', 'pt' => 'whois.ripe.net', 'ro' => 'whois.ripe.net', 'ru' => 'whois.ripe.net', 'se' => 'whois.ripe.net', 'sg' => 'whois.nic.net.sg', 'si' => 'whois.ripe.net', 'sk' => 'whois.ripe.net', 'sm' => 'whois.ripe.net', 'su' => 'whois.ripe.net', 'tn' => 'whois.ripe.net', 'tr' => 'whois.ripe.net', 'tw' => 'whois.twnic.net', 'ua' => 'whois.ripe.net', 'uk' => 'whois.nic.uk', 'gov.uk' => 'whois.ja.net', 'ac.uk' => 'whois.ja.net', 'eu.com' => 'whois.centralnic.com', 'uk.com' => 'whois.centralnic.com', 'uk.net' => 'whois.centralnic.com', 'gb.com' => 'whois.centralnic.com', 'gb.net' => 'whois.centralnic.com', 'us' => 'whois.isi.edu', 'va' => 'whois.ripe.net', 'yu' => 'whois.ripe.net', ); my %ARGS = ( 'whois.nic.ad.jp' => { 'S' => '/e' }, 'whois.internic.net' => { 'P' => '=' }, 'whois.networksolutions.com' => { 'P' => '=' }, ); sub register_parser { my ( $self, %args ) = @_; $self->{ _PARSERS }->{ $args{ Name } } = {} unless $args{ Retain }; #set Retain to keep parser entries already present for ( keys %{ $args{ Parser } } ) { $self->{ _PARSERS }->{ $args{ Name } }->{$_} = $args{ Parser }->{$_}; } return 1; } sub register_association { my ( $self, %args ) = @_; foreach my $server ( keys %args ) { # Update our table for looking up the whois server => parser $self->{ _WHOIS_PARSER }->{ $server } = $args{ $server }->[0]; # Save name of whois server and associated parser # Update our table of domains and their associated server #$self->{ _DOMAIN_ASSOC }->{ $_ } = $server for ( @{$args{ $server }}->[1]); $self->{ _DOMAIN_ASSOC }->{ $_ } = $server for ( @{$args{ $server }->[1]}); #from Paul Fuchs }; return 1; } sub register_cache { my ( $self, $cache ) = @_; return ${ $self->{ _CACHE } } = $cache if $cache; } sub server { my $self = shift; return $self->{ Server }; } sub guess_server_details { my ( $self, $domain ) = @_; $domain = lc $domain; my $ip=$domain=~/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/; #processing an IP? my ( $server, $parser ); my ( $Dserver, $Dparser ) = $ip ? ( 'whois.arin.net', { %{ $self->{ _PARSERS }->{ ARIN } } }) : ( 'whois.internic.net', { %{ $self->{ _PARSERS }->{ INTERNIC } } } ) ; #figure out what our server and parser should be if ($ip) { $server= $self->{ Server } ? $self->{ Server } : 'whois.arin.net' ; } else { $domain =~ s/.*\.(\w+\.\w+)$/$1/; #peels off the last two elements $server = $self->{ _DOMAIN_ASSOC }->{ $domain }; unless ($server) { $domain =~ s/.*\.(\w+)$/$1/; #peels off the last element $server = $self->{ _DOMAIN_ASSOC }->{ $domain }; } } $parser = $self->{ _PARSERS }->{ $self->{ _WHOIS_PARSER }->{ $server } } if ($server); #print "domain $domain server $server parser $parser\n"; return $server ? [$server, $parser] : [$Dserver, $Dparser]; }; sub new { my ( $class, %args ) = @_; my $self = {}; $self->{ _PARSERS } = \%PARSERS; $self->{ _DOMAIN_ASSOC } = \%DOMAIN_ASSOC; $self->{ _WHOIS_PARSER } = \%WHOIS_PARSER; $self->{ _CACHE } = $args{Cache} || \$CACHE; $self->{ _EXPIRE } = $args{Expire} || \$EXPIRE; $self->{ _ARGS } = \%ARGS; bless $self, $class; $self->personality ( %args ); $self->lookup () if $self->{ Domain }; return $self; } sub personality { my ( $self, %args ) = @_; #set all attributes that were passed in for ( keys %args ) {chomp $args{ $_} if defined($args{ $_}); $self->{ $_ }=$args{ $_ } } $self->{ Parser } = $self->{ _PARSERS }->{ $args{ Format } } if $args{ Format }; #lets you pick an alternate parser set #if we don't have a whois server to use, guess based on the Domain (or IP) unless ( $self->{ Server } ) { my $res = $self->guess_server_details ( $self->{ Domain } ); ( $self->{ Server }, undef ) = @$res; } #if there is already a Parser defined for this server, use it if ( $self->{ _PARSERS }->{ $self->{ Server }}) { $self->{ Parser } = $self->{ _PARSERS }->{ $self->{ Server }}; } #if we still don't have a Parser to use, guess based on the Domain (or IP) unless ( $self->{ Parser } ) { my $res = $self->guess_server_details ( $self->{ Domain } ); ( undef, $self->{ Parser } ) = @$res; } #set these if they aren't already set $self->{ Timeout } = $TIMEOUT unless $self->{ Timeout }; $self->{ Error } = $ERROR unless $self->{ Error }; $self->{ Retries } = $RETRIES unless $self->{ Retries }; } sub lookup { my ( $self, %args ) = @_; $self->personality ( %args ); my $cache = $args{ Cache } || ${ $self->{ _CACHE } }; $self->{ Domain }=~s/^www\.//; #trim leading www. if present; internic doesn't like it print "looking up ", $self->{ Domain }, " on ", $self->{ Server }, "\n" if ($self->{ Verbose }); #see if we already have a response in the cache, unless told not to unless ( $self->{ Nocache } ) { READCACHE: { if ( -d $cache ) { last READCACHE unless -e "$cache/$domain"; my $current = time (); open D, "$cache/$domain" || last READCACHE; my @stat = stat ( D ); if ( $current - $stat[ 9 ] > ${ $self->{ _EXPIRE } } ) { close D; last READCACHE; } undef $/; $self->{ Response } = ; return 1; } } } #connect to whois server my $server = $self->{ Server }; my $suffix = $self->{ _ARGS }->{ $server }->{S} || ''; my $prefix = $self->{ _ARGS }->{ $server }->{P} || ''; my $sock = $self->_connect ( $self->{ Server } ); return undef unless $sock; #request whois info, then disconnect print $sock $prefix , $self->{ Domain }, "$suffix\r\n"; #print $sock $prefix , $domain, "$suffix\r\n"; { local $/; undef $/; $self->{ Response } = <$sock>; } close($sock); undef $sock; #did we get forwarded? my $fw = eval { ($self->forwardwhois)[0] }; my @fwa = (); #if ($fw =~ m/\n/) { unless (defined($fw) && $fw=~/whois/) { #if forwardwhois is a server, use it; otherwise... #ARIN forwarding kludge 08/06/2002 rwoodard if ( $self->{ Server } eq "whois.arin.net" ) { $fw="whois.apnic.net" if ( $self->{ Response }=~/Asia Pacific Network Information (?:Center|Centre)/misg ); $fw="whois.ripe.net" if ( $self->{ Response }=~/European Regional Internet Registry|RIPE Network Coordination Centre/misg ); $fw="whois.lacnic.net" if ( $self->{ Response }=~/Latin American and Caribbean IP address Regional Registry/misg ); } #APNIC forwarding kludge 08/06/2002 rwoodard elsif ($self->{ Server } eq 'whois.apnic.net') { $fw="whois.krnic.net" if ($self->{ Response }=~/Allocated to KRNIC/misg ); $fw="whois.twnic.net" if ($self->{ Response }=~/Allocated to TWNIC/misg ); } else { #original code @fwa = $self->{ Response } =~ m/\s+$self->{ Domain }\n.*?\n*?\s*?.*?Whois Server: (.*?)(?=\n)/isg; $fw = shift @fwa; return undef unless (defined($fw) && length($fw) > 0); # pattern not found } return undef if (defined($fw) && $self->{ Server } eq $fw); #avoid infinite loop } if ( defined($fw) && $fw ne "" ) { $self->personality( Format => $self->{_WHOIS_PARSER}->{$fw}); return undef if ($self->{ Server } eq $fw); #avoid infinite loop $self->{ Server } = $fw; $self->{ Response } = ""; #$self->lookup(); print " forwarded to server $fw\n" if ($self->{ Verbose }); $self->lookup( Server => "$fw" ); #from Paul Fuchs } #are there multiple netblocks? If so, do we pursue them? (ARIN only for now) if ( $self->{Server} eq 'whois.arin.net' && $self->multiple && $self->{ Bottom_netblock } && $self->net_handle ) { my @netblocks=($self->net_handle); my $cnt=$#netblocks; #print "mult blocks, looking up ", $netblocks[$cnt], " on ", $self->{ Server }, "\n"; $self->{ Response } = ""; $self->lookup( Domain => $netblocks[$cnt], Server => $self->{ Server }); } #cache the response if ( (-d $cache) && (!($self->{Nocache})) ) { open D, "> $cache/$domain" || return; print D $self->{ Response }; close D; } #print "done with lookup\n"; } sub AUTOLOAD { my $self = shift; return undef unless $self->{ Response }; #we didn't get a response, nothing to return my $key = $AUTOLOAD; $key =~ s/.*://; #croak "Method $key not defined" unless exists ${$self->{ Parser }}{$key}; return undef unless exists ${$self->{ Parser }}{$key}; #don't croak(), just don't do anything my @matches = (); if ( ref(${$self->{ Parser } }{ $key }) !~ /^CODE/ ) { #not an array or hash, i.e. a regexp #get everything in the response that matches the regexp; each match is an element in the array @matches = $self->{ Response } =~ /${ $self->{ Parser } }{ $key }/sg; #print "matches for $key: @matches\n"; } else { #assumes you have defined your own subroutine with register_parser, pass the whole response to it @matches = &{ $self->{ Parser }{$key}}($self->response); } my @tmp = split /\n/, join "\n", @matches; for (@tmp) { s/^\s+//; s/\s+$//; chomp }; #trim leading/trailing whitespace and newline #print "tmp: @tmp\n"; #depending on calling context, return an array or a newline-delimited string return wantarray ? @tmp : join "\n", @tmp ; } sub response { my $self = shift; return $self->{ Response }; } sub _connect { my $self = shift; my $machine = shift; my $error = $self->{Error}; my $maxtries = $self->{Retries}; my $sock; my $retries=0; until ($sock || $retries == $maxtries) { #print " connecting to $machine\n"; $sock = new IO::Socket::INET PeerAddr => $machine, PeerPort => 'whois', Proto => 'tcp', Timeout => $self->{Timeout}; # or &$error( "[$@]" ); $retries++ unless ($sock); print "try $retries failed\n" if ( $self->{ Verbose } && !$sock); } &$error( "[$@]" ) unless ($sock); $sock->autoflush if $sock; return $sock; } sub ignore {} sub DESTROY {} #from Gregory Karpinsky 'True Value.'; =head1 NAME Net::XWhois - Whois Client Interface for Perl5. =head1 SYNOPSIS use Net::XWhois; $whois = new Net::XWhois Domain => "vipul.net" ; $whois = new Net::XWhois Domain => "bit.ch", Server => "domreg.nic.ch", Retain => 1, Parser => { nameservers => 'nserver:\s+(\S+)', }; =head1 DESCRIPTION The Net::XWhois class provides a generic client framework for doing Whois queries and parsing server response. The class maintains an array of top level domains and whois servers associated with them. This allows the class to transparently serve requests for different tlds, selecting servers appropriate for the tld. The server details are, therefore, hidden from the user and "vipul.net" (from InterNIC), gov.ru (from RIPE) and "bit.ch" (from domreg.nic.ch) are queried in the same manner. This behaviour can be overridden by specifying different bindings at object construction or by registering associations with the class. See L<"register_associations()"> and L<"new()">. One of the more important goals of this module is to enable the design of consistent and predictable interfaces to incompatible whois response formats. The Whois RFC (954) does not define a template for presenting server data; consequently there is a large variation in layout styles as well as content served across servers. (There is, however, a new standard called RPSL (RFC2622) used by RIPE (http://www.ripe.net), the European main whois server.) To overcome this, Net::XWhois maintains another set of tables - parsing rulesets - for a few, popular response formats. (See L<"%PARSERS">). These parsing tables contain section names (labels) together with regular expressions that I the corresponding section text. The section text is accessed "via" labels which are available as data instance methods at runtime. By following a consistent nomenclature for labels, semantically related information encoded in different formats can be accessed with the same methods. =head1 CONSTRUCTOR =over 4 =item new () Creates a Net::XWhois object. Takes an optional argument, a hash, that specifies the domain name to be queried. Calls lookup() if a name is provided. The argument hash can also specify a whois server, a parsing rule-set or a parsing rule-set format. (See L<"personality()">). Omitting the argument will create an "empty" object that can be used for accessing class data. =item personality () Alters an object's personality. Takes a hash with following arguments. (Note: These arguments can also be passed to the constructor). =over 8 =item B Domain name to be queried. =item B Server to query. =item B Parsing Rule-set. See L<"%PARSERS">. Parser => { name => 'domain:\s+(\S+)\n', nameservers => 'nserver:\s+(\S+)', contact_emails => 'e-mail:\s+(\S+\@\S+)', }; =item B A pre-defined parser format like INTERNIC, INTERNIC_FORMAT, RIPE, RIPE_CH, JAPAN etc. Format => 'INTERNIC_CONTACT', =item B Force XWhois to ignore the cached records. =item B Determines how a network connection error is handled. By default Net::XWhois will croak() if it can't connect to the whois server. The Error attribute specifies a function call name that will be invoked when a network connection error occurs. Possible values are croak, carp, confess (imported from Carp.pm) and ignore (a blank function provided by Net::XWhois). You can, of course, write your own function to do error handling, in which case you'd have to provide a fully qualified function name. Example: main::logerr. =item B Timeout value for establishing a network connection with the server. The default value is 60 seconds. =back =back =head1 CLASS DATA & ACCESS METHODS =over 4 =item %PARSERS An associative array that contains parsing rule-sets for various response formats. Keys of this array are format names and values are hash refs that contain section labels and corresponding parser code. The parser code can either be a regex or a reference to a subroutine. In the case of a subroutine, the whois 'response' information is available to the sub in $_[0]. Parsers can be added and extended with the register_parser() method. Also see L. my %PARSERS = ( INTERNIC => { contact_tech => 'Technical Contact.*?\n(.*?)(?=\... contact_zone => 'Zone Contact.*?\n(.*?)(?=\s*\n[... contact_billing => 'Billing Contact.*?\n(.*?)(?=\s*... contact_emails => \&example_email_parser }, { etc. ... }, ); sub example_email_parser { # Note that the default internal implemenation for # the INTERNIC parser is not a user-supplied code # block. This is just an instructive example. my @matches = $_[0] =~ /(\S+\@\S+)/sg; return @matches; } See XWhois.pm for the complete definition of %PARSERS. =item %WHOIS_PARSER %WHOIS_PARSER is a table that associates each whois server with their output format. my %WHOIS_PARSER = ( 'whois.ripe.net' => 'RPSL', 'whois.nic.mil' => 'INTERNIC', 'whois.nic.ad.jp' => 'JAPAN', 'whois.domainz.net.nz' => 'GENERIC', 'whois.nic.gov' => 'INTERNIC', 'whois.nic.ch' => 'RIPE_CH', 'whois.twnic.net' => 'TAIWAN', 'whois.internic.net' => 'INTERNIC', 'whois.nic.net.sg' => 'RIPE', 'whois.aunic.net' => 'RIPE', 'whois.cdnnet.ca' => 'CANADA', 'whois.nic.uk' => 'INTERNIC', 'whois.krnic.net' => 'KOREA', 'whois.isi.edu' => 'INTERNIC', 'whois.norid.no' => 'RPSL', ( etc.....) Please note that there is a plethora of output formats, allthough there are RFCs on this issue, like for instance RFC2622, there are numerous different formats being used! =item %DOMAIN_ASSOC %DOMAIN_ASSOC is a table that associates top level domain names with their respective whois servers. You'd need to modity this table if you wish to extend the module's functionality to handle a new set of domain names. Or alter existing information. I provides an interface to this array. See XWhois.pm for the complete definition. my %DOMAIN_ASSOC = ( 'al' => 'whois.ripe.net', 'am' => 'whois.ripe.net', 'at' => 'whois.ripe.net', 'au' => 'whois.aunic.net', 'az' => 'whois.ripe.net', 'ba' => 'whois.ripe.net', 'be' => 'whois.ripe.net', =item register_parser() Extend, modify and override entries in %PARSERS. Accepts a hash with three keys - Name, Retain and Parser. If the format definition for the specified format exists and the Retain key holds a true value, the keys from the specified Parser are added to the existing definition. A new definition is created when Retain is false/not specified. my $w = new Net::Whois; $w->register_parser ( Name => "INTERNIC", Retain => 1, Parser => { creation_time => 'created on (\S*?)\.\n', some_randome_entity => \&random_entity_subroutine }; Instructions on how to create a workable random_entity_subroutine are availabe in the I<%PARSERS> description, above. =item register_association() Override and add entries to %ASSOC. Accepts a hash that contains representation specs for a whois server. The keys of this hash are server machine names and values are list-refs to the associated response formats and the top-level domains handled by the servers. See Net/XWhois.pm for more details. my $w = new Net::XWhois; $w->register_association ( 'whois.aunic.net' => [ RIPE, [ qw/au/ ] ] ); =item register_cache() By default, Net::XWhois caches all whois responses and commits them, as separate files, to /tmp/whois. register_cache () gets and sets the cache directory. Setting to "undef" will disable caching. $w->register_cache ( "/some/place/else" ); $w->register_cache ( undef ); =back =head1 OBJECT METHODS =over 4 =item B Access to the whois response data is provided via AUTOLOADED methods specified in the Parser. The methods return scalar or list data depending on the context. Internic Parser provides the following methods: =over 8 =item B Domain name. =item B Domain Status when provided. When the domain is on hold, this method will return "On Hold" string. =item B Nameservers along with their IPs. =item B Registrant's name and address. =item B Administrative Contact. =item B Technical Contact. =item B Zone Contact. =item B Billing Contact. =item B List of email addresses of contacts. =item B List of contact handles in the response. Contact and Domain handles are valid query data that can be used instead of contact and domain names. =item B List of domain handles in the response. Can be used for sorting out reponses that contain multiple domain names. =back =item B Does a whois lookup on the specified domain. Takes the same arguments as new(). my $w = new Net::XWhois; $w->lookup ( Domain => "perl.com" ); print $w->response (); =back =head1 EXAMPLES Look at example programs that come with this package. "whois" is a replacement for the standard RIPE/InterNIC whois client. "creation" overrides the Parser value at object init and gets the Creation Time of an InterNIC domain. "creation2" does the same thing by extending the Class Parser. "contacts" queries and prints information about domain's Tech/Billing/Admin contacts. contribs/ containts parsers for serveral whois servers, which have not been patched into the module. =head1 AUTHOR Vipul Ved Prakash =head1 THANKS Curt Powell , Matt Spiers , Richard Dice , Robert Chalmers , Steinar Overbeck Cook , Steve Weathers , Robert Puettmann , Martin H . Sluka" , Rob Woodard , Jon Gilbert, Erik Aronesty for patches, bug-reports and many cogent suggestions. =head1 MAILING LIST Net::XWhois development has moved to the sourceforge mailing list, xwhois-devel@lists.sourceforge.net. Please send all Net::XWhois related communication directly to the list address. The subscription interface is at: http://lists.sourceforge.net/mailman/listinfo/xwhois-devel =head1 SEE ALSO RFC 954 RFC 2622 =head1 COPYRIGHT Copyright (c) 1998-2001 Vipul Ved Prakash. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Net/Daemon.pm000066600000110662150777111550007056 0ustar00# -*- perl -*- # # $Id: Daemon.pm,v 1.3 1999/09/26 14:50:12 joe Exp $ # # Net::Daemon - Base class for implementing TCP/IP daemons # # Copyright (C) 1998, Jochen Wiedmann # Am Eisteich 9 # 72555 Metzingen # Germany # # Phone: +49 7123 14887 # Email: joe@ispsoft.de # # All rights reserved. # # You may distribute this package under the terms of either the GNU # General Public License or the Artistic License, as specified in the # Perl README file. # ############################################################################ require 5.004; use strict; use Getopt::Long (); use Symbol (); use IO::Socket (); use Config (); use Net::Daemon::Log (); use POSIX (); package Net::Daemon; $Net::Daemon::VERSION = '0.43'; @Net::Daemon::ISA = qw(Net::Daemon::Log); # # Regexps aren't thread safe, as of 5.00502 :-( (See the test script # regexp-threads.) # $Net::Daemon::RegExpLock = 1; use vars qw($exit); ############################################################################ # # Name: Options (Class method) # # Purpose: Returns a hash ref of command line options # # Inputs: $class - This class # # Result: Options array; any option is represented by a hash ref; # used keys are 'template', a string suitable for describing # the option to Getopt::Long::GetOptions and 'description', # a string for the Usage message # ############################################################################ sub Options ($) { { 'catchint' => { 'template' => 'catchint!', 'description' => '--nocatchint ' . "Try to catch interrupts when calling system\n" . ' ' . 'functions like bind(), recv()), ...' }, 'childs' => { 'template' => 'childs=i', 'description' => '--childs ' . 'Set number of preforked childs, implies mode=single.' }, 'chroot' => { 'template' => 'chroot=s', 'description' => '--chroot ' . 'Change rootdir to given after binding to port.' }, 'configfile' => { 'template' => 'configfile=s', 'description' => '--configfile ' . 'Read options from config file .' }, 'debug' => { 'template' => 'debug', 'description' => '--debug ' . 'Turn debugging mode on'}, 'facility' => { 'template' => 'facility=s', 'description' => '--facility ' . 'Syslog facility; defaults to \'daemon\'' }, 'group' => { 'template' => 'group=s', 'description' => '--group ' . 'Change gid to given group after binding to port.' }, 'help' => { 'template' => 'help', 'description' => '--help ' . 'Print this help message' }, 'localaddr' => { 'template' => 'localaddr=s', 'description' => '--localaddr ' . 'IP number to bind to; defaults to INADDR_ANY' }, 'localpath' => { 'template' => 'localpath=s', 'description' => '--localpath ' . 'UNIX socket domain path to bind to' }, 'localport' => { 'template' => 'localport=s', 'description' => '--localport ' . 'Port number to bind to' }, 'logfile' => { 'template' => 'logfile=s', 'description' => '--logfile ' . 'Force logging to ' }, 'loop-child' => { 'template' => 'loop-child', 'description' => '--loop-child ' . 'Create a child process for loops' }, 'loop-timeout' => { 'template' => 'loop-timeout=f', 'description' => '--loop-timeout ' . 'Looping mode, seconds per loop' }, 'mode' => { 'template' => 'mode=s', 'description' => '--mode ' . 'Operation mode (threads, fork or single)' }, 'pidfile' => { 'template' => 'pidfile=s', 'description' => '--pidfile ' . 'Use as PID file' }, 'proto' => { 'template' => 'proto=s', 'description' => '--proto ' . 'transport layer protocol: tcp (default) or unix' }, 'user' => { 'template' => 'user=s', 'description' => '--user ' . 'Change uid to given user after binding to port.' }, 'version' => { 'template' => 'version', 'description' => '--version ' . 'Print version number and exit' } } } ############################################################################ # # Name: Version (Class method) # # Purpose: Returns version string # # Inputs: $class - This class # # Result: Version string; suitable for printed by "--version" # ############################################################################ sub Version ($) { "Net::Daemon server, Copyright (C) 1998, Jochen Wiedmann"; } ############################################################################ # # Name: Usage (Class method) # # Purpose: Prints usage message # # Inputs: $class - This class # # Result: Nothing; aborts with error status # ############################################################################ sub Usage ($) { my($class) = shift; my($options) = $class->Options(); my(@options) = sort (keys %$options); print STDERR "Usage: $0 \n\nPossible options are:\n\n"; my($key); foreach $key (sort (keys %$options)) { my($o) = $options->{$key}; print STDERR " ", $o->{'description'}, "\n" if $o->{'description'}; } print STDERR "\n", $class->Version(), "\n"; exit(1); } ############################################################################ # # Name: ReadConfigFile (Instance method) # # Purpose: Reads the config file. # # Inputs: $self - Instance # $file - config file name # $options - Hash of command line options; these are not # really for being processed by this method. We pass # it just in case. The new() method will process them # at a later time. # $args - Array ref of other command line options. # ############################################################################ sub ReadConfigFile { my($self, $file, $options, $args) = @_; if (! -f $file) { $self->Fatal("No such config file: $file"); } my $copts = do $file; if ($@) { $self->Fatal("Error while processing config file $file: $@"); } if (!$copts || ref($copts) ne 'HASH') { $self->Fatal("Config file $file did not return a hash ref."); } # Override current configuration with config file options. while (my($var, $val) = each %$copts) { $self->{$var} = $val; } } ############################################################################ # # Name: new (Class method) # # Purpose: Constructor # # Inputs: $class - This class # $attr - Hash ref of attributes # $args - Array ref of command line arguments # # Result: Server object for success, error message otherwise # ############################################################################ sub new ($$;$) { my($class, $attr, $args) = @_; my($self) = $attr ? \%$attr : {}; bless($self, (ref($class) || $class)); my $options = ($self->{'options'} ||= {}); $self->{'args'} ||= []; if ($args) { my @optList = map { $_->{'template'} } values(%{$class->Options()}); local @ARGV = @$args; if (!Getopt::Long::GetOptions($options, @optList)) { $self->Usage(); } @{$self->{'args'}} = @ARGV; if ($options->{'help'}) { $self->Usage(); } if ($options->{'version'}) { print STDERR $self->Version(), "\n"; exit 1; } } my $file = $options->{'configfile'} || $self->{'configfile'}; if ($file) { $self->ReadConfigFile($file, $options, $args); } while (my($var, $val) = each %$options) { $self->{$var} = $val; } if ($self->{'childs'}) { $self->{'mode'} = 'single'; } elsif (!defined($self->{'mode'})) { if (eval { require thread }) { $self->{'mode'} = 'ithreads'; } elsif (eval { require Thread }) { $self->{'mode'} = 'threads'; } else { my $fork = 0; if ($^O ne "MSWin32") { my $pid = eval { fork() }; if (defined($pid)) { if (!$pid) { exit; } # Child $fork = 1; wait; } } if ($fork) { $self->{'mode'} = 'fork'; } else { $self->{'mode'} = 'single'; } } } if ($self->{'mode'} eq 'ithreads') { require threads; } elsif ($self->{'mode'} eq 'threads') { require Thread; } elsif ($self->{'mode'} eq 'fork') { # Initialize forking mode ... } elsif ($self->{'mode'} eq 'single') { # Initialize single mode ... } else { $self->Fatal("Unknown operation mode: $self->{'mode'}"); } $self->{'catchint'} = 1 unless exists($self->{'catchint'}); $self->Debug("Server starting in operation mode $self->{'mode'}"); if ($self->{'childs'}) { $self->Debug("Preforking $self->{'childs'} child processes ..."); } $self; } sub Clone ($$) { my($proto, $client) = @_; my $self = { %$proto }; $self->{'socket'} = $client; $self->{'parent'} = $proto; bless($self, ref($proto)); $self; } ############################################################################ # # Name: Accept (Instance method) # # Purpose: Called for authentication purposes # # Inputs: $self - Server instance # # Result: TRUE, if the client has successfully authorized, FALSE # otherwise. # ############################################################################ sub Accept ($) { my $self = shift; my $socket = $self->{'socket'}; my $clients = $self->{'clients'}; my $from = $self->{'proto'} eq 'unix' ? "Unix socket" : sprintf("%s, port %s", $socket->peerhost(), $socket->peerport()); # Host based authorization if ($self->{'clients'}) { my ($name, $aliases, $addrtype, $length, @addrs); if ($self->{'proto'} eq 'unix') { ($name, $aliases, $addrtype, $length, @addrs) = ('localhost', '', Socket::AF_INET(), length(Socket::IN_ADDR_ANY()), Socket::inet_aton('127.0.0.1')); } else { ($name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr($socket->peeraddr(), Socket::AF_INET()); } my @patterns = @addrs ? map { Socket::inet_ntoa($_) } @addrs : $socket->peerhost(); push(@patterns, $name) if ($name); push(@patterns, split(/ /, $aliases)) if $aliases; my $found; OUTER: foreach my $client (@$clients) { if (!$client->{'mask'}) { $found = $client; last; } my $masks = ref($client->{'mask'}) ? $client->{'mask'} : [ $client->{'mask'} ]; # # Regular expressions aren't thread safe, as of # 5.00502 :-( # my $lock; $lock = lock($Net::Daemon::RegExpLock) if ($self->{'mode'} eq 'threads'); foreach my $mask (@$masks) { foreach my $alias (@patterns) { if ($alias =~ /$mask/) { $found = $client; last OUTER; } } } } if (!$found || !$found->{'accept'}) { $self->Error("Access not permitted from $from"); return 0; } $self->{'client'} = $found; } $self->Debug("Accepting client from $from"); 1; } ############################################################################ # # Name: Run (Instance method) # # Purpose: Does the real work # # Inputs: $self - Server instance # # Result: Nothing; returning will make the connection to be closed # ############################################################################ sub Run ($) { } ############################################################################ # # Name: Done (Instance method) # # Purpose: Called by the server before doing an accept(); a TRUE # value makes the server terminate. # # Inputs: $self - Server instance # # Result: TRUE or FALSE # # Bugs: Doesn't work in forking mode. # ############################################################################ sub Done ($;$) { my $self = shift; $self->{'done'} = shift if @_; $self->{'done'} } ############################################################################ # # Name: Loop (Instance method) # # Purpose: If $self->{'loop-timeout'} option is set, then this method # will be called every "loop-timeout" seconds. # # Inputs: $self - Server instance # # Result: Nothing; aborts in case of trouble. Note, that this is *not* # trapped and forces the server to exit. # ############################################################################ sub Loop { } ############################################################################ # # Name: ChildFunc (Instance method) # # Purpose: If possible, spawn a child process which calls a given # method. In server mode single the method is called # directly. # # Inputs: $self - Instance # $method - Method name # @args - Method arguments # # Returns: Nothing; aborts in case of problems. # ############################################################################ sub ChildFunc { my($self, $method, @args) = @_; if ($self->{'mode'} eq 'single') { $self->$method(@args); } elsif ($self->{'mode'} eq 'threads') { my $startfunc = sub { my $self = shift; my $method = shift; $self->$method(@_) }; Thread->new($startfunc, $self, $method, @args) or die "Failed to create a new thread: $!"; } elsif ($self->{'mode'} eq 'ithreads') { my $startfunc = sub { my $self = shift; my $method = shift; $self->$method(@_) }; threads->new($startfunc, $self, $method, @args) or die "Failed to create a new thread: $!"; } else { my $pid = fork(); die "Cannot fork: $!" unless defined $pid; return if $pid; # Parent $self->$method(@args); # Child exit(0); } } ############################################################################ # # Name: Bind (Instance method) # # Purpose: Binds to a port; if successfull, it never returns. Instead # it accepts connections. For any connection a new thread is # created and the Accept method is executed. # # Inputs: $self - Server instance # # Result: Error message in case of failure # ############################################################################ sub HandleChild { my $self = shift; $self->Debug("New child starting ($self)."); eval { if (!$self->Accept()) { $self->Error('Refusing client'); } else { $self->Debug('Accepting client'); $self->Run(); } }; $self->Error("Child died: $@") if $@; $self->Debug("Child terminating."); $self->Close(); }; sub SigChildHandler { my $self = shift; my $ref = shift; return 'IGNORE' if $self->{'mode'} eq 'fork' || $self->{'childs'}; return undef; # Don't care for childs. } sub Bind ($) { my $self = shift; my $fh; my $child_pid; my $reaper = $self->SigChildHandler(\$child_pid); $SIG{'CHLD'} = $reaper if $reaper; if (!$self->{'socket'}) { $self->{'proto'} ||= ($self->{'localpath'}) ? 'unix' : 'tcp'; if ($self->{'proto'} eq 'unix') { my $path = $self->{'localpath'} or $self->Fatal('Missing option: localpath'); unlink $path; $self->Fatal("Can't remove stale Unix socket ($path): $!") if -e $path; my $old_umask = umask 0; $self->{'socket'} = IO::Socket::UNIX->new('Local' => $path, 'Listen' => $self->{'listen'} || 10) or $self->Fatal("Cannot create Unix socket $path: $!"); umask $old_umask; } else { $self->{'socket'} = IO::Socket::INET->new ( 'LocalAddr' => $self->{'localaddr'}, 'LocalPort' => $self->{'localport'}, 'Proto' => $self->{'proto'} || 'tcp', 'Listen' => $self->{'listen'} || 10, 'Reuse' => 1) or $self->Fatal("Cannot create socket: $!"); } } $self->Log('notice', "Server starting"); if ((my $pidfile = ($self->{'pidfile'} || '')) ne 'none') { $self->Debug("Writing PID to $pidfile"); my $fh = Symbol::gensym(); $self->Fatal("Cannot write to $pidfile: $!") unless (open (OUT, ">$pidfile") and (print OUT "$$\n") and close(OUT)); } if (my $dir = $self->{'chroot'}) { $self->Debug("Changing root directory to $dir"); if (!chroot($dir)) { $self->Fatal("Cannot change root directory to $dir: $!"); } } if (my $group = $self->{'group'}) { $self->Debug("Changing GID to $group"); my $gid; if ($group !~ /^\d+$/) { if (defined(my $gid = getgrnam($group))) { $group = $gid; } else { $self->Fatal("Cannot determine gid of $group: $!"); } } $( = ($) = $group); } if (my $user = $self->{'user'}) { $self->Debug("Changing UID to $user"); my $uid; if ($user !~ /^\d+$/) { if (defined(my $uid = getpwnam($user))) { $user = $uid; } else { $self->Fatal("Cannot determine uid of $user: $!"); } } $< = ($> = $user); } if ($self->{'childs'}) { my $pid; my $childpids = $self->{'childpids'} = {}; for (my $n = 0; $n < $self->{'childs'}; $n++) { $pid = fork(); die "Cannot fork: $!" unless defined $pid; if (!$pid) { #Child $self->{'mode'} = 'single'; last; } # Parent $childpids->{$pid} = 1; } if ($pid) { # Parent waits for childs in a loop, then exits ... # We could also terminate the parent process, but # if the parent is still running we can kill the # whole group by killing the childs. my $childpid; $exit = 0; $SIG{'TERM'} = sub { die }; $SIG{'INT'} = sub { die }; eval { do { $childpid = wait; delete $childpids->{$childpid}; $self->Debug("Child $childpid has exited"); } until ($childpid <= 0 || $exit || keys(%$childpids) == 0); }; my @pids = keys %{$self -> {'childpids'}}; if (@pids) { $self->Debug("kill TERM childs: " . join(",", @pids)); kill 'TERM', @pids if @pids ; # send a TERM to all childs } exit (0); } } my $time = $self->{'loop-timeout'} ? (time() + $self->{'loop-timeout'}) : 0; my $client; while (!$self->Done()) { undef $child_pid; my $rin = ''; vec($rin,$self->{'socket'}->fileno(),1) = 1; my($rout, $t); if ($time) { my $tm = time(); $t = $time - $tm; $t = 0 if $t < 0; $self->Debug("Loop time: time=$time now=$tm, t=$t"); } my($nfound) = select($rout=$rin, undef, undef, $t); if ($nfound < 0) { if (!$child_pid and ($! != POSIX::EINTR() or !$self->{'catchint'})) { $self->Fatal("%s server failed to select(): %s", ref($self), $self->{'socket'}->error() || $!); } } elsif ($nfound) { my $client = $self->{'socket'}->accept(); if (!$client) { if (!$child_pid and ($! != POSIX::EINTR() or !$self->{'catchint'})) { $self->Error("%s server failed to accept: %s", ref($self), $self->{'socket'}->error() || $!); } } else { if ($self->{'debug'}) { my $from = $self->{'proto'} eq 'unix' ? 'Unix socket' : sprintf('%s, port %s', # SE 19990917: display client data!! $client->peerhost(), $client->peerport()); $self->Debug("Connection from $from"); } my $sth = $self->Clone($client); $self->Debug("Child clone: $sth\n"); $sth->ChildFunc('HandleChild') if $sth; if ($self->{'mode'} eq 'fork') { close($client); } } } if ($time) { my $t = time(); if ($t >= $time) { $time = $t; if ($self->{'loop-child'}) { $self->ChildFunc('Loop'); } else { $self->Loop(); } $time += $self->{'loop-timeout'}; } } } $self->Log('notice', "%s server terminating", ref($self)); } sub Close { my $socket = shift->{'socket'}; $socket->close() if $socket; } 1; __END__ =head1 NAME Net::Daemon - Perl extension for portable daemons =head1 SYNOPSIS # Create a subclass of Net::Daemon require Net::Daemon; package MyDaemon; @MyDaemon::ISA = qw(Net::Daemon); sub Run ($) { # This function does the real work; it is invoked whenever a # new connection is made. } =head1 DESCRIPTION Net::Daemon is an abstract base class for implementing portable server applications in a very simple way. The module is designed for Perl 5.005 and threads, but can work with fork() and Perl 5.004. The Net::Daemon class offers methods for the most common tasks a daemon needs: Starting up, logging, accepting clients, authorization, restricting its own environment for security and doing the true work. You only have to override those methods that aren't appropriate for you, but typically inheriting will safe you a lot of work anyways. =head2 Constructors $server = Net::Daemon->new($attr, $options); $connection = $server->Clone($socket); Two constructors are available: The B method is called upon startup and creates an object that will basically act as an anchor over the complete program. It supports command line parsing via L. Arguments of B are I<$attr>, an hash ref of attributes (see below) and I<$options> an array ref of options, typically command line arguments (for example B<\@ARGV>) that will be passed to B. The second constructor is B: It is called whenever a client connects. It receives the main server object as input and returns a new object. This new object will be passed to the methods that finally do the true work of communicating with the client. Communication occurs over the socket B<$socket>, B's argument. Possible object attributes and the corresponding command line arguments are: =over 4 =item I (B<--nocatchint>) On some systems, in particular Solaris, the functions accept(), read() and so on are not safe against interrupts by signals. For example, if the user raises a USR1 signal (as typically used to reread config files), then the function returns an error EINTR. If the I option is on (by default it is, use B<--nocatchint> to turn this off), then the package will ignore EINTR errors whereever possible. =item I (B<--chroot=dir>) (UNIX only) After doing a bind(), change root directory to the given directory by doing a chroot(). This is usefull for security operations, but it restricts programming a lot. For example, you typically have to load external Perl extensions before doing a chroot(), or you need to create hard links to Unix sockets. This is typically done in the config file, see the --configfile option. See also the --group and --user options. If you don't know chroot(), think of an FTP server where you can see a certain directory tree only after logging in. =item I An array ref with a list of clients. Clients are hash refs, the attributes I (0 for denying access and 1 for permitting) and I, a Perl regular expression for the clients IP number or its host name. See L<"Access control"> below. =item I (B<--configfile=file>) Net::Daemon supports the use of config files. These files are assumed to contain a single hash ref that overrides the arguments of the new method. However, command line arguments in turn take precedence over the config file. See the L<"Config File"> section below for details on the config file. =item I (B<--debug>) Turn debugging mode on. Mainly this asserts that logging messages of level "debug" are created. =item I (B<--facility=mode>) (UNIX only) Facility to use for L. The default is B. =item I (B<--group=gid>) After doing a bind(), change the real and effective GID to the given. This is usefull, if you want your server to bind to a privileged port (<1024), but don't want the server to execute as root. See also the --user option. GID's can be passed as group names or numeric values. =item I (B<--localaddr=ip>) By default a daemon is listening to any IP number that a machine has. This attribute allows to restrict the server to the given IP number. =item I (B<--localpath=path>) If you want to restrict your server to local services only, you'll prefer using Unix sockets, if available. In that case you can use this option for setting the path of the Unix socket being created. This option implies B<--proto=unix>. =item I (B<--localport=port>) This attribute sets the port on which the daemon is listening. It must be given somehow, as there's no default. =item I (B<--logfile=file>) By default logging messages will be written to the syslog (Unix) or to the event log (Windows NT). On other operating systems you need to specify a log file. The special value "STDERR" forces logging to stderr. =item I (B<--loop-child>) This option forces creation of a new child for loops. (See the I option.) By default the loops are serialized. =item I (B<--loop-timeout=secs>) Some servers need to take an action from time to time. For example the Net::Daemon::Spooler attempts to empty its spooling queue every 5 minutes. If this option is set to a positive value (zero being the default), then the server will call its Loop method every "loop-timeout" seconds. Don't trust too much on the precision of the interval: It depends on a number of factors, in particular the execution time of the Loop() method. The loop is implemented by using the I\n". $form."

\n"; if ($this->capb_backup) { $form.="\n"; } $form.="\n"; $form.="\n\n\n"; my $query; do { $this->showclient($httpheader . $form); $this->closeclient; $this->client; my @get=grep { /^GET / } split(/\r\n/, $this->commands); my $get=shift @get; my ($qs)=$get=~m/^GET\s+.*?\?(.*?)(?:\s+.*)?$/; $query=CGI->new($qs); } until ($query->param('formid') eq $formid); if ($this->capb_backup && $query->param('back') ne '') { return ''; } foreach my $id ($query->param) { next unless $idtoelt{$id}; $idtoelt{$id}->value($query->param($id)); delete $idtoelt{$id}; } foreach my $elt (values %idtoelt) { $elt->value(''); } return 1; } 1 Debconf/FrontEnd/Text.pm000066600000000233150777111550011120 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::FrontEnd::Text; use strict; use base qw(Debconf::FrontEnd::Readline); 1 Debconf/DbDriver.pm000066600000004467150777111550010173 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::DbDriver; use Debconf::Log qw{:all}; use strict; use base 1.01; # ensure that they don't have a broken perl installation use fields qw(name readonly required backup failed accept_type reject_type accept_name reject_name); our %drivers; sub new { my Debconf::DbDriver $this=shift; unless (ref $this) { $this = fields::new($this); } $this->{required}=1; $this->{readonly}=0; $this->{failed}=0; my %params=@_; foreach my $field (keys %params) { if ($field eq 'readonly' || $field eq 'required' || $field eq 'backup') { $this->{$field}=1,next if lc($params{$field}) eq "true"; $this->{$field}=0,next if lc($params{$field}) eq "false"; } elsif ($field=~/^(accept|reject)_/) { $this->{$field}=qr/$params{$field}/i; } $this->{$field}=$params{$field}; } unless (exists $this->{name}) { $this->{name}="(unknown)"; $this->error("no name specified"); } $drivers{$this->{name}} = $this; $this->init; return $this; } sub init {} sub error { my $this=shift; if ($this->{required}) { warn('DbDriver "'.$this->{name}.'":', @_); exit 1; } else { warn('DbDriver "'.$this->{name}.'" warning:', @_); } } sub driver { my $this=shift; my $name=shift; return $drivers{$name}; } sub accept { my $this=shift; my $name=shift; my $type=shift; return if $this->{failed}; if ((exists $this->{accept_name} && $name !~ /$this->{accept_name}/) || (exists $this->{reject_name} && $name =~ /$this->{reject_name}/)) { debug "db $this->{name}" => "reject $name"; return; } if (exists $this->{accept_type} || exists $this->{reject_type}) { if (! defined $type || ! length $type) { my $template = Debconf::Template->get($this->getfield($name, 'template')); return 1 unless $template; # no type to act on $type=$template->type || ''; } return if exists $this->{accept_type} && $type !~ /$this->{accept_type}/; return if exists $this->{reject_type} && $type =~ /$this->{reject_type}/; } return 1; } sub ispassword { my $this=shift; my $item=shift; my $template=$this->getfield($item, 'template'); return unless defined $template; $template=Debconf::Template->get($template); return unless $template; my $type=$template->type || ''; return 1 if $type eq 'password'; return 0; } 1 Debconf/Element/Kde/Password.pm000066600000001135150777111550012355 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::Password; use strict; use QtCore4; use QtGui4; use base qw(Debconf::Element::Kde); sub create { my $this=shift; $this->SUPER::create(@_); $this->startsect; $this->widget(Qt::LineEdit($this->cur->top)); $this->widget->show; $this->widget->setEchoMode(2); $this->addwidget($this->description); $this->addhelp; $this->addwidget($this->widget); $this->endsect; } sub value { my $this=shift; my $text = $this->widget->text(); $text = $this->question->value if $text eq ''; return $text; } 1 Debconf/Element/Kde/Multiselect.pm000066600000002331150777111550013044 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::Multiselect; use strict; use QtCore4; use QtGui4; use base qw(Debconf::Element::Kde Debconf::Element::Multiselect); use Debconf::Encoding qw(to_Unicode); sub create { my $this=shift; my @choices = $this->question->choices_split; my %default = map { $_ => 1 } $this->translate_default; $this->SUPER::create(@_); $this->startsect; $this->adddescription; $this->addhelp; my @buttons; for (my $i=0; $i <= $#choices; $i++) { $buttons[$i] = Qt::CheckBox($this->cur->top); $buttons[$i]->setText(to_Unicode($choices[$i])); $buttons[$i]->show; $buttons[$i]->setChecked($default{$choices[$i]} ? 1 : 0); $this->addwidget($buttons[$i]); } $this->buttons(\@buttons); $this->endsect; } sub value { my $this = shift; my @buttons = @{$this->buttons}; my ($ret, $val); my @vals; $this->question->template->i18n(''); my @choices=$this->question->choices_split; $this->question->template->i18n(1); for (my $i = 0; $i <= $#choices; $i++) { if ($buttons [$i] -> isChecked()) { push @vals, $choices[$i]; } } return join(', ', $this->order_values(@vals)); } *visible = \&Debconf::Element::Multiselect::visible; 1 Debconf/Element/Kde/Error.pm000066600000000523150777111550011644 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::Error; use strict; use Debconf::Gettext; use QtCore4; use QtGui4; use base qw(Debconf::Element::Kde); sub create { my $this=shift; $this->SUPER::create(@_); $this->startsect; $this->adddescription; $this->addhelp; $this->endsect; } 1 Debconf/Element/Kde/Select.pm000066600000002073150777111550011774 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::Select; use strict; use QtCore4; use QtGui4; use base qw(Debconf::Element::Kde Debconf::Element::Select); use Debconf::Encoding qw(to_Unicode); sub create { my $this=shift; my $default=$this->translate_default; my @choices=map { to_Unicode($_) } $this->question->choices_split; $this->SUPER::create(@_); $this->startsect; $this->widget(Qt::ComboBox($this->cur->top)); $this->widget->show; $this->widget->addItems(\@choices); if (defined($default) and length($default) != 0) { for (my $i = 0 ; $i < @choices ; $i++) { if ($choices[$i] eq $default ) { $this->widget->setCurrentIndex($i);# //FIXME find right index to_Unicode($default)); last; } } } $this->addwidget($this->description); $this->addhelp; $this->addwidget($this->widget); $this->endsect; } sub value { my $this=shift; my @choices=$this->question->choices_split; return $this->translate_to_C_uni($this->widget->currentText()); } *visible = \&Debconf::Element::Select::visible; 1 Debconf/Element/Kde/String.pm000066600000001174150777111550012024 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::String; use strict; use QtCore4; use QtGui4; use base qw(Debconf::Element::Kde); use Debconf::Encoding qw(to_Unicode); sub create { my $this=shift; $this->SUPER::create(@_); $this->startsect; $this->widget(Qt::LineEdit($this->cur->top)); my $default=''; $default=$this->question->value if defined $this->question->value; $this->widget->setText(to_Unicode($default)); $this->adddescription; $this->addhelp; $this->addwidget ($this->widget); $this->endsect; } sub value { my $this=shift; return $this->widget->text(); } 1 Debconf/Element/Kde/Note.pm000066600000000555150777111550011465 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::Note; use strict; use Debconf::Gettext; use Qt; use Debconf::Element::Noninteractive::Note; use base qw(Debconf::Element::Kde); sub create { my $this=shift; $this->SUPER::create(@_); $this->startsect; $this->adddescription; $this->addhelp; $this->endsect; } 1 Debconf/Element/Kde/Text.pm000066600000000503150777111550011475 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::Text; use strict; use Debconf::Gettext; use Qt; use base qw(Debconf::Element::Kde); sub create { my $this=shift; $this->SUPER::create(@_); $this->startsect; $this->adddescription; # yeah, that's all $this->endsect; } 1 Debconf/Element/Kde/Boolean.pm000066600000001332150777111550012131 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::Boolean; use strict; use QtCore4; use QtGui4; use base qw(Debconf::Element::Kde); use Debconf::Encoding qw(to_Unicode); sub create { my $this=shift; $this->SUPER::create(@_); $this->startsect; $this->widget(Qt::CheckBox( to_Unicode($this->question->description))); $this->widget->setChecked(($this->question->value eq 'true') ? 1 : 0); $this->widget->setText(to_Unicode($this->question->description)); $this->adddescription; $this->addhelp; $this->addwidget($this->widget); $this->endsect; } sub value { my $this = shift; if ($this -> widget -> isChecked) { return "true"; } else { return "false"; } } 1 Debconf/Element/Kde/Progress.pm000066600000002214150777111550012356 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::Progress; use strict; use QtCore4; use QtGui4; use base qw(Debconf::Element::Kde); use Debconf::Encoding qw(to_Unicode); sub start { my $this=shift; my $description=to_Unicode($this->question->description); my $frontend=$this->frontend; $this->SUPER::create($frontend->frame); $this->startsect; $this->addhelp; $this->adddescription; my $vbox = Qt::VBoxLayout($this->widget); $this->progress_bar(Qt::ProgressBar($this->cur->top)); $this->progress_bar->setMinimum($this->progress_min()); $this->progress_bar->setMaximum($this->progress_max()); $this->progress_bar->show; $this->addwidget($this->progress_bar); $this->progress_label(Qt::Label($this->cur->top)); $this->progress_label->show; $this->addwidget($this->progress_label); $this->endsect; } sub set { my $this=shift; my $value=shift; $this->progress_cur($value); $this->progress_bar->setValue($this->progress_cur); return 1; } sub info { my $this=shift; my $question=shift; $this->progress_label->setText(to_Unicode($question->description)); return 1; } sub stop { } 1; Debconf/Element/Noninteractive/Password.pm000066600000000263150777111550014643 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::Password; use strict; use base qw(Debconf::Element::Noninteractive); 1 Debconf/Element/Noninteractive/Multiselect.pm000066600000000266150777111550015336 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::Multiselect; use strict; use base qw(Debconf::Element::Noninteractive); 1 Debconf/Element/Noninteractive/Error.pm000066600000002766150777111550014144 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::Error; use strict; use Text::Wrap; use Debconf::Gettext; use Debconf::Config; use Debconf::Log ':all'; use base qw(Debconf::Element::Noninteractive); sub show { my $this=shift; if ($this->question->flag('seen') ne 'true') { $this->sendmail(gettext("Debconf was not configured to display this error message, so it mailed it to you.")); } $this->value(''); } sub sendmail { my $this=shift; my $footer=shift; return unless length Debconf::Config->admin_email; if (-x '/usr/bin/mail') { debug user => "mailing a note"; my $title=gettext("Debconf").": ". $this->frontend->title." -- ". $this->question->description; unless (open(MAIL, "|-")) { # child exec("mail", "-s", $title, Debconf::Config->admin_email) or return ''; } my $old_columns=$Text::Wrap::columns; $Text::Wrap::columns=75; if ($this->question->extended_description ne '') { print MAIL wrap('', '', $this->question->extended_description); } else { print MAIL wrap('', '', $this->question->description); } print MAIL "\n\n"; my $hostname=`hostname -f 2>/dev/null`; if (! defined $hostname) { $hostname="unknown system"; } print MAIL "-- \n", sprintf(gettext("Debconf, running at %s"), $hostname, "\n"); print MAIL "[ ", wrap('', '', $footer), " ]\n" if $footer; close MAIL or return ''; $Text::Wrap::columns=$old_columns; $this->question->flag('seen', 'true'); return 1; } } 1 Debconf/Element/Noninteractive/Select.pm000066600000001132150777111550014254 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::Select; use strict; use base qw(Debconf::Element::Noninteractive); sub show { my $this=shift; $this->question->template->i18n(''); my @choices=$this->question->choices_split; $this->question->template->i18n(1); my $value=$this->question->value; $value='' unless defined $value; my $inlist=0; map { $inlist=1 if $_ eq $value } @choices; if (! $inlist) { if (@choices) { $this->value($choices[0]); } else { $this->value(''); } } else { $this->value($value); } } 1 Debconf/Element/Noninteractive/String.pm000066600000000261150777111550014305 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::String; use strict; use base qw(Debconf::Element::Noninteractive); 1 Debconf/Element/Noninteractive/Note.pm000066600000000257150777111550013751 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::Note; use strict; use base qw(Debconf::Element::Noninteractive); 1 Debconf/Element/Noninteractive/Text.pm000066600000000342150777111550013763 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::Text; use strict; use base qw(Debconf::Element::Noninteractive); sub show { my $this=shift; $this->value(''); } 1 Debconf/Element/Noninteractive/Boolean.pm000066600000000262150777111550014417 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::Boolean; use strict; use base qw(Debconf::Element::Noninteractive); 1 Debconf/Element/Noninteractive/Progress.pm000066600000000402150777111550014640 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive::Progress; use strict; use base qw(Debconf::Element::Noninteractive); sub start { } sub set { return 1; } sub info { return 1; } sub stop { } 1; Debconf/Element/Multiselect.pm000066600000001624150777111550012345 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Multiselect; use strict; use base qw(Debconf::Element::Select); sub order_values { my $this=shift; my %vals=map { $_ => 1 } @_; $this->question->template->i18n(''); my @ret=grep { $vals{$_} } $this->question->choices_split; $this->question->template->i18n(1); return @ret; } sub visible { my $this=shift; my @choices=$this->question->choices_split; return ($#choices >= 0); } sub translate_default { my $this=shift; my @choices=$this->question->choices_split; $this->question->template->i18n(''); my @choices_c=$this->question->choices_split; $this->question->template->i18n(1); my @ret; foreach my $c_default ($this->question->value_split) { foreach (my $x=0; $x <= $#choices; $x++) { push @ret, $choices[$x] if $choices_c[$x] eq $c_default; } } return @ret; } 1 Debconf/Element/Dialog/Password.pm000066600000001262150777111550013052 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::Password; use strict; use base qw(Debconf::Element); sub show { my $this=shift; my ($text, $lines, $columns)= $this->frontend->makeprompt($this->question); my @params=('--passwordbox'); push @params, $this->frontend->dashsep if $this->frontend->dashsep; push @params, ($text, $lines + $this->frontend->spacer, $columns); my $ret=$this->frontend->showdialog($this->question, @params); if (! defined $ret || $ret eq '') { my $default=''; $default=$this->question->value if defined $this->question->value; $this->value($default); } else { $this->value($ret); } } 1 Debconf/Element/Dialog/Multiselect.pm000066600000003450150777111550013543 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::Multiselect; use strict; use base qw(Debconf::Element::Multiselect); use Debconf::Encoding qw(width); sub show { my $this=shift; my ($text, $lines, $columns)= $this->frontend->makeprompt($this->question, -2); my $screen_lines=$this->frontend->screenheight - $this->frontend->spacer; my @params=(); my @choices=$this->question->choices_split; my %value = map { $_ => 1 } $this->translate_default; my $menu_height=$#choices + 1; if ($lines + $#choices + 2 >= $screen_lines) { $menu_height = $screen_lines - $lines - 4; if ($menu_height < 3 && $#choices + 1 > 2) { $this->frontend->showtext($this->question, $this->question->extended_description); ($text, $lines, $columns)=$this->frontend->sizetext($this->question->description); $menu_height=$#choices + 1; if ($lines + $#choices + 2 >= $screen_lines) { $menu_height = $screen_lines - $lines - 4; } } } $lines=$lines + $menu_height + $this->frontend->spacer; my $selectspacer = $this->frontend->selectspacer; my $c=1; foreach (@choices) { push @params, ($_, ""); push @params, ($value{$_} ? 'on' : 'off'); if ($columns < width($_) + $selectspacer) { $columns = width($_) + $selectspacer; } } if ($this->frontend->dashsep) { unshift @params, $this->frontend->dashsep; } @params=('--separate-output', '--checklist', $text, $lines, $columns, $menu_height, @params); my $value=$this->frontend->showdialog($this->question, @params); if (defined $value) { $this->value(join(", ", $this->order_values( map { $this->translate_to_C($_) } split(/\n/, $value)))); } else { my $default=''; $default=$this->question->value if defined $this->question->value; $this->value($default); } } 1 Debconf/Element/Dialog/Error.pm000066600000000513150777111550012337 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::Error; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->showtext($this->question, $this->question->description."\n\n". $this->question->extended_description ); $this->value(''); } 1 Debconf/Element/Dialog/Select.pm000066600000002506150777111550012471 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::Select; use strict; use base qw(Debconf::Element::Select); use Debconf::Encoding qw(width); sub show { my $this=shift; my ($text, $lines, $columns)= $this->frontend->makeprompt($this->question, -2); my $screen_lines=$this->frontend->screenheight - $this->frontend->spacer; my $default=$this->translate_default; my @params=(); my @choices=$this->question->choices_split; my $menu_height=$#choices + 1; if ($lines + $#choices + 2 >= $screen_lines) { $menu_height = $screen_lines - $lines - 4; } $lines=$lines + $menu_height + $this->frontend->spacer; my $c=1; my $selectspacer = $this->frontend->selectspacer; foreach (@choices) { push @params, $_, ''; if ($columns < width($_) + $selectspacer) { $columns = width($_) + $selectspacer; } } if ($this->frontend->dashsep) { unshift @params, $this->frontend->dashsep; } @params=('--default-item', $default, '--menu', $text, $lines, $columns, $menu_height, @params); my $value=$this->frontend->showdialog($this->question, @params); if (defined $value) { $this->value($this->translate_to_C($value)) if defined $value; } else { my $default=''; $default=$this->question->value if defined $this->question->value; $this->value($default); } } 1 Debconf/Element/Dialog/String.pm000066600000001424150777111550012516 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::String; use strict; use base qw(Debconf::Element); sub show { my $this=shift; my ($text, $lines, $columns)= $this->frontend->makeprompt($this->question); my $default=''; $default=$this->question->value if defined $this->question->value; my @params=('--inputbox'); push @params, $this->frontend->dashsep if $this->frontend->dashsep; push @params, ($text, $lines + $this->frontend->spacer, $columns, $default); my $value=$this->frontend->showdialog($this->question, @params); if (defined $value) { $this->value($value); } else { my $default=''; $default=$this->question->value if defined $this->question->value; $this->value($default); } } 1 Debconf/Element/Dialog/Note.pm000066600000000512150777111550012152 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::Note; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->showtext($this->question, $this->question->description."\n\n". $this->question->extended_description ); $this->value(''); } 1 Debconf/Element/Dialog/Text.pm000066600000000512150777111550012171 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::Text; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->showtext($this->question, $this->question->description."\n\n". $this->question->extended_description ); $this->value(''); } 1 Debconf/Element/Dialog/Boolean.pm000066600000001331150777111550012624 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::Boolean; use strict; use base qw(Debconf::Element); sub show { my $this=shift; my @params=('--yesno'); push @params, $this->frontend->dashsep if $this->frontend->dashsep; push @params, $this->frontend->makeprompt($this->question, 1); if (defined $this->question->value && $this->question->value eq 'false') { unshift @params, '--defaultno'; } my ($ret, $value)=$this->frontend->showdialog($this->question, @params); if (defined $ret) { $this->value($ret eq 0 ? 'true' : 'false'); } else { my $default=''; $default=$this->question->value if defined $this->question->value; $this->value($default); } } 1 Debconf/Element/Dialog/Progress.pm000066600000003466150777111550013064 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Dialog::Progress; use strict; use base qw(Debconf::Element); sub _communicate { my $this=shift; my $data=shift; my $dialoginput = $this->frontend->dialog_input_wtr; print $dialoginput $data; } sub _percent { my $this=shift; use integer; return (($this->progress_cur() - $this->progress_min()) * 100 / ($this->progress_max() - $this->progress_min())); } sub start { my $this=shift; $this->frontend->title($this->question->description); my ($text, $lines, $columns); if (defined $this->_info) { ($text, $lines, $columns)=$this->frontend->sizetext($this->_info->description); } else { ($text, $lines, $columns)=$this->frontend->sizetext(' '); } if ($this->frontend->screenwidth - $this->frontend->columnspacer > $columns) { $columns = $this->frontend->screenwidth - $this->frontend->columnspacer; } my @params=('--gauge'); push @params, $this->frontend->dashsep if $this->frontend->dashsep; push @params, ($text, $lines + $this->frontend->spacer, $columns, $this->_percent); $this->frontend->startdialog($this->question, 1, @params); $this->_lines($lines); $this->_columns($columns); } sub set { my $this=shift; my $value=shift; $this->progress_cur($value); $this->_communicate($this->_percent . "\n"); return 1; } sub info { my $this=shift; my $question=shift; $this->_info($question); my ($text, $lines, $columns)=$this->frontend->sizetext($question->description); if ($lines > $this->_lines or $columns > $this->_columns) { $this->stop; $this->start; } $this->_communicate( sprintf("XXX\n%d\n%s\nXXX\n%d\n", $this->_percent, $text, $this->_percent)); return 1; } sub stop { my $this=shift; $this->frontend->waitdialog; $this->frontend->title($this->frontend->requested_title); } 1 Debconf/Element/Web/Password.pm000066600000000743150777111550012373 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::Password; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $_=$this->question->extended_description; s/\n/\n
\n/g; $_.="\n

\n"; my $default=''; $default=$this->question->value if defined $this->question->value; my $id=$this->id; $_.="".$this->question->description."\n"; return $_; } 1 Debconf/Element/Web/Multiselect.pm000066600000001676150777111550013071 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::Multiselect; use strict; use base qw(Debconf::Element::Multiselect); sub show { my $this=shift; $_=$this->question->extended_description; s/\n/\n
\n/g; $_.="\n

\n"; my %value = map { $_ => 1 } $this->translate_default; my $id=$this->id; $_.="".$this->question->description."\n\n"; return $_; } sub value { my $this=shift; return $this->SUPER::value() unless @_; my @values=@_; $this->question->template->i18n(''); my @choices=$this->question->choices_split; $this->question->template->i18n(1); $this->SUPER::value(join(', ', $this->order_values(map { $choices[$_] } @values))); } 1 Debconf/Element/Web/Error.pm000066600000000240150777111550011652 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::Error; use strict; use base qw(Debconf::Element::Web::Text); 1 Debconf/Element/Web/Select.pm000066600000001555150777111550012012 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::Select; use strict; use base qw(Debconf::Element::Select); sub show { my $this=shift; $_=$this->question->extended_description; s/\n/\n
\n/g; $_.="\n

\n"; my $default=$this->translate_default; my $id=$this->id; $_.="".$this->question->description."\n\n"; return $_; } sub value { my $this=shift; return $this->SUPER::value() unless @_; my $value=shift; $this->question->template->i18n(''); my @choices=$this->question->choices_split; $this->question->template->i18n(1); $this->SUPER::value($choices[$value]); } 1 Debconf/Element/Web/String.pm000066600000000723150777111550012035 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::String; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $_=$this->question->extended_description; s/\n/\n
\n/g; $_.="\n

\n"; my $default=''; $default=$this->question->value if defined $this->question->value; my $id=$this->id; $_.="".$this->question->description."\n"; return $_; } 1 Debconf/Element/Web/Note.pm000066600000000237150777111550011474 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::Note; use strict; use base qw(Debconf::Element::Web::Text); 1 Debconf/Element/Web/Text.pm000066600000000473150777111550011515 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::Text; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $_=$this->question->extended_description; s/\n/\n
\n/g; $_.="\n

\n"; return "".$this->question->description."$_

"; } 1 Debconf/Element/Web/Boolean.pm000066600000001224150777111550012143 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::Boolean; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $_=$this->question->extended_description; s/\n/\n
\n/g; $_.="\n

\n"; my $default=''; $default=$this->question->value if defined $this->question->value; my $id=$this->id; $_.="\n". $this->question->description.""; return $_; } sub value { my $this=shift; return $this->SUPER::value() unless @_; my $value=shift; $this->SUPER::value($value eq 'on' ? 'true' : 'false'); } 1 Debconf/Element/Web/Progress.pm000066600000000347150777111550012375 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Web::Progress; use strict; use base qw(Debconf::Element); sub start { } sub set { return 1; } sub info { return 1; } sub stop { } 1; Debconf/Element/Gnome.pm000066600000005614150777111550011123 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome; use strict; use utf8; use Gtk2; use Debconf::Gettext; use Debconf::Encoding qw(to_Unicode); use base qw(Debconf::Element); sub init { my $this=shift; $this->hbox(Gtk2::VBox->new(0, 10)); $this->hline1(Gtk2::HBox->new(0, 10)); $this->hline1->show; $this->line1(Gtk2::VBox->new(0, 10)); $this->line1->show; $this->line1->pack_end ($this->hline1, 1, 1, 0); $this->hline2(Gtk2::HBox->new(0, 10)); $this->hline2->show; $this->line2(Gtk2::VBox->new(0, 10)); $this->line2->show; $this->line2->pack_end ($this->hline2, 1, 1, 0); $this->vbox(Gtk2::VBox->new(0, 5)); $this->vbox->pack_start($this->line1, 0, 0, 0); $this->vbox->pack_start($this->line2, 1, 1, 0); $this->vbox->show; $this->hbox->pack_start($this->vbox, 1, 1, 0); $this->hbox->show; $this->fill(0); $this->expand(0); $this->multiline(0); } sub addwidget { my $this=shift; my $widget=shift; if ($this->multiline == 0) { $this->hline1->pack_start($widget, 1, 1, 0); } else { $this->hline2->pack_start($widget, 1, 1, 0); } } sub adddescription { my $this=shift; my $description=to_Unicode($this->question->description); my $label=Gtk2::Label->new($description); $label->show; $this->line1->pack_start($label, 0, 0, 0); } sub addbutton { my $this=shift; my $text = shift; my $callback = shift; my $button = Gtk2::Button->new_with_mnemonic(to_Unicode($text)); $button->show; $button->signal_connect("clicked", $callback); my $vbox = Gtk2::VBox->new(0, 0); $vbox->show; $vbox->pack_start($button, 1, 0, 0); $this->hline1->pack_end($vbox, 0, 0, 0); } sub create_message_dialog { my $this = shift; my $type = shift; my $title = shift; my $text = shift; my $dialog = Gtk2::Dialog->new_with_buttons(to_Unicode($title), undef, "modal", "gtk-close", "close"); $dialog->set_border_width(3); my $hbox = Gtk2::HBox->new(0); $dialog->vbox->pack_start($hbox, 1, 1, 5); $hbox->show; my $alignment = Gtk2::Alignment->new(0.5, 0.0, 1.0, 0.0); $hbox->pack_start($alignment, 1, 1, 3); $alignment->show; my $image = Gtk2::Image->new_from_stock($type, "dialog"); $alignment->add($image); $image->show; my $label = Gtk2::Label->new(to_Unicode($text)); $label->set_line_wrap(1); $hbox->pack_start($label, 1, 1, 2); $label->show; $dialog->run; $dialog->destroy; } sub addhelp { my $this=shift; my $help=$this->question->extended_description; return unless length $help; $this->addbutton(gettext("_Help"), sub { $this->create_message_dialog("gtk-dialog-info", gettext("Help"), to_Unicode($help)); }); if (defined $this->tip ){ $this->tooltips( Gtk2::Tooltips->new() ); $this->tooltips->set_tip($this->tip, to_Unicode($help), undef ); $this->tooltips->enable; } } sub value { my $this=shift; return ''; } 1 Debconf/Element/Select.pm000066600000003676150777111550011303 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Select; use strict; use Debconf::Log ':all'; use Debconf::Gettext; use base qw(Debconf::Element); use Debconf::Encoding qw(to_Unicode); sub visible { my $this=shift; my @choices=$this->question->choices_split; if (@choices > 1) { return 1; } else { debug 'developer' => 'Not displaying select list '. $this->question->name.' with '. (@choices+0).' choice'.((@choices == 0) ? 's' : ''); return 0; } } sub translate_default { my $this=shift; my @choices=$this->question->choices_split; $this->question->template->i18n(''); my @choices_c=$this->question->choices_split; $this->question->template->i18n(1); my $c_default=''; $c_default=$this->question->value if defined $this->question->value; foreach (my $x=0; $x <= $#choices; $x++) { return $choices[$x] if $choices_c[$x] eq $c_default; } return ''; } sub translate_to_C { my $this=shift; my $value=shift; my @choices=$this->question->choices_split; $this->question->template->i18n(''); my @choices_c=$this->question->choices_split; $this->question->template->i18n(1); for (my $x=0; $x <= $#choices; $x++) { return $choices_c[$x] if $choices[$x] eq $value; } debug developer => sprintf(gettext("Input value, \"%s\" not found in C choices! This should never happen. Perhaps the templates were incorrectly localized."), $value); return ''; } sub translate_to_C_uni { my $this=shift; my $value=shift; my @choices=$this->question->choices_split; $this->question->template->i18n(''); my @choices_c=$this->question->choices_split; $this->question->template->i18n(1); for (my $x=0; $x <= $#choices; $x++) { return $choices_c[$x] if to_Unicode($choices[$x]) eq $value; } debug developer => sprintf(gettext("Input value, \"%s\" not found in C choices! This should never happen. Perhaps the templates were incorrectly localized."), $value); return ''; } 1 Debconf/Element/Teletype/Password.pm000066600000001165150777111550013450 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::Password; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->display( $this->question->extended_description."\n"); my $default=''; $default=$this->question->value if defined $this->question->value; my $value=$this->frontend->prompt_password( prompt => $this->question->description, default => $default, question => $this->question, ); return unless defined $value; if ($value eq '') { $value=$default; } $this->frontend->display("\n"); $this->value($value); } 1 Debconf/Element/Teletype/Multiselect.pm000066600000003553150777111550014143 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::Multiselect; use strict; use Debconf::Gettext; use Debconf::Config; use base qw(Debconf::Element::Multiselect Debconf::Element::Teletype::Select); sub show { my $this=shift; my @selected; my $none_of_the_above=gettext("none of the above"); my @choices=$this->question->choices_split; my %value = map { $_ => 1 } $this->translate_default; if ($this->frontend->promptdefault && $this->question->value ne '') { push @choices, $none_of_the_above; } my @completions=@choices; my $i=1; my %choicenum=map { $_ => $i++ } @choices; $this->frontend->display($this->question->extended_description."\n"); my $default; if (Debconf::Config->terse eq 'false') { $this->printlist(@choices); $this->frontend->display("\n(".gettext("Enter the items you want to select, separated by spaces.").")\n"); push @completions, 1..@choices; $default=join(" ", map { $choicenum{$_} } grep { $value{$_} } @choices); } else { $default=join(" ", grep { $value{$_} } @choices); } while (1) { $_=$this->frontend->prompt( prompt => $this->question->description, default => $default, completions => [@completions], completion_append_character => " ", question => $this->question, ); return unless defined $_; @selected=split(/[ ,]+/, $_); @selected=map { $this->expandabbrev($_, @choices) } @selected; next if grep { $_ eq '' } @selected; if ($#selected > 0) { map { next if $_ eq $none_of_the_above } @selected; } last; } $this->frontend->display("\n"); if (defined $selected[0] && $selected[0] eq $none_of_the_above) { $this->value(''); } else { my %selected=map { $_ => 1 } @selected; $this->value(join(', ', $this->order_values( map { $this->translate_to_C($_) } keys %selected))); } } 1 Debconf/Element/Teletype/Error.pm000066600000000252150777111550012733 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::Error; use strict; use base qw(Debconf::Element::Teletype::Text); 1 Debconf/Element/Teletype/Select.pm000066600000006314150777111550013066 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::Select; use strict; use Debconf::Config; use POSIX qw(ceil); use base qw(Debconf::Element::Select); sub expandabbrev { my $this=shift; my $input=shift; my @choices=@_; if (Debconf::Config->terse eq 'false' and $input=~m/^[0-9]+$/ and $input ne '0' and $input <= @choices) { return $choices[$input - 1]; } my @matches=(); foreach (@choices) { return $_ if /^\Q$input\E$/; push @matches, $_ if /^\Q$input\E/; } return $matches[0] if @matches == 1; if (! @matches) { foreach (@choices) { return $_ if /^\Q$input\E$/i; push @matches, $_ if /^\Q$input\E/i; } return $matches[0] if @matches == 1; } return ''; } sub printlist { my $this=shift; my @choices=@_; my $width=$this->frontend->screenwidth; my $choice_min=length $choices[0]; map { $choice_min = length $_ if length $_ < $choice_min } @choices; my $max_cols=int($width / (2 + length(@choices) + 2 + $choice_min)) - 1; $max_cols = $#choices if $max_cols > $#choices; my $max_lines; my $num_cols; COLUMN: for ($num_cols = $max_cols; $num_cols >= 0; $num_cols--) { my @col_width; my $total_width; $max_lines=ceil(($#choices + 1) / ($num_cols + 1)); next if ceil(($#choices + 1) / $max_lines) - 1 < $num_cols; foreach (my $choice=1; $choice <= $#choices + 1; $choice++) { my $choice_length=2 + length(@choices) + 2 + length($choices[$choice - 1]); my $current_col=ceil($choice / $max_lines) - 1; if (! defined $col_width[$current_col] || $choice_length > $col_width[$current_col]) { $col_width[$current_col]=$choice_length; $total_width=0; map { $total_width += $_ } @col_width; next COLUMN if $total_width > $width; } } last; } my $line=0; my $max_len=0; my $col=0; my @output=(); for (my $choice=0; $choice <= $#choices; $choice++) { $output[$line] .= " ".($choice+1).". " . $choices[$choice]; if (length $output[$line] > $max_len) { $max_len = length $output[$line]; } if (++$line >= $max_lines) { if ($col++ != $num_cols) { for (my $l=0; $l <= $#output; $l++) { $output[$l] .= ' ' x ($max_len - length $output[$l]); } } $line=0; $max_len=0; } } @output = map { s/\s+$//; $_ } @output; map { $this->frontend->display_nowrap($_) } @output; } sub show { my $this=shift; my $default=$this->translate_default; my @choices=$this->question->choices_split; my @completions=@choices; $this->frontend->display($this->question->extended_description."\n"); if (Debconf::Config->terse eq 'false') { for (my $choice=0; $choice <= $#choices; $choice++) { if ($choices[$choice] eq $default) { $default=$choice + 1; last; } } $this->printlist(@choices); $this->frontend->display("\n"); push @completions, 1..@choices; } my $value; while (1) { $value=$this->frontend->prompt( prompt => $this->question->description, default => $default ? $default : '', completions => [@completions], question => $this->question, ); return unless defined $value; $value=$this->expandabbrev($value, @choices); last if $value ne ''; } $this->frontend->display("\n"); $this->value($this->translate_to_C($value)); } 1 Debconf/Element/Teletype/String.pm000066600000001075150777111550013114 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::String; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->display( $this->question->extended_description."\n"); my $default=''; $default=$this->question->value if defined $this->question->value; my $value=$this->frontend->prompt( prompt => $this->question->description, default => $default, question => $this->question, ); return unless defined $value; $this->frontend->display("\n"); $this->value($value); } 1 Debconf/Element/Teletype/Note.pm000066600000000623150777111550012551 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::Note; use strict; use base qw(Debconf::Element); sub visible { my $this=shift; return (Debconf::Config->terse eq 'false'); } sub show { my $this=shift; $this->frontend->display($this->question->description."\n\n". $this->question->extended_description."\n"); $this->value(''); } 1 Debconf/Element/Teletype/Text.pm000066600000000473150777111550012573 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::Text; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->display($this->question->description."\n\n". $this->question->extended_description."\n"); $this->value(''); } 1 Debconf/Element/Teletype/Boolean.pm000066600000002103150777111550013216 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::Boolean; use strict; use Debconf::Gettext; use base qw(Debconf::Element); sub show { my $this=shift; my $y=gettext("yes"); my $n=gettext("no"); $this->frontend->display($this->question->extended_description."\n"); my $default=''; $default=$this->question->value if defined $this->question->value; if ($default eq 'true') { $default=$y; } elsif ($default eq 'false') { $default=$n; } my $value=''; while (1) { $_=$this->frontend->prompt( default => $default, completions => [$y, $n], prompt => $this->question->description, question => $this->question, ); return unless defined $_; if (substr($y, 0, 1) ne substr($n, 0, 1)) { $y=substr($y, 0, 1); $n=substr($n, 0, 1); } if (/^\Q$y\E/i) { $value='true'; last; } elsif (/^\Q$n\E/i) { $value='false'; last; } if (/^y/i) { $value='true'; last; } elsif (/^n/i) { $value='false'; last; } } $this->frontend->display("\n"); $this->value($value); } 1 Debconf/Element/Teletype/Progress.pm000066600000001445150777111550013453 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Teletype::Progress; use strict; use base qw(Debconf::Element); sub start { my $this=shift; $this->frontend->title($this->question->description); $this->frontend->display(''); $this->last(0); } sub set { my $this=shift; my $value=shift; $this->progress_cur($value); use integer; my $new = ($this->progress_cur() - $this->progress_min()) * 100 / ($this->progress_max() - $this->progress_min()); $this->last(0) if $new < $this->last; return if $new / 10 == $this->last / 10; $this->last($new); $this->frontend->display("..$new%"); return 1; } sub info { return 1; } sub stop { my $this=shift; $this->frontend->display("\n"); $this->frontend->title($this->frontend->requested_title); } 1; Debconf/Element/Kde.pm000066600000004211150777111550010551 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Kde::ElementWidget; use QtCore4; use QtCore4::isa @ISA = qw(Qt::Widget); use QtGui4; sub NEW { shift->SUPER::NEW ($_[0]); this->{mytop} = undef; } sub settop { this->{mytop} = shift; } sub init { this->{toplayout} = Qt::VBoxLayout(this); this->{mytop} = Qt::Widget(this); this->{toplayout}->addWidget (this->{mytop}); this->{layout} = Qt::VBoxLayout(); this->{mytop}->setLayout(this->{layout}); } sub destroy { this->{toplayout} -> removeWidget (this->{mytop}); undef this->{mytop}; } sub top { return this->{mytop}; } sub addwidget { this->{layout}->addWidget(@_); } sub addlayout { this->{layout}->addLayout (@_); } package Debconf::Element::Kde; use strict; use QtCore4; use QtGui4; use Debconf::Gettext; use base qw(Debconf::Element); use Debconf::Element::Kde::ElementWidget; use Debconf::Encoding qw(to_Unicode); sub create { my $this=shift; $this->parent(shift); $this->top(Debconf::Element::Kde::ElementWidget($this->parent, undef, undef, undef)); $this->top->init; $this->top->show; } sub destroy { my $this=shift; $this->top(undef); } sub addwidget { my $this=shift; my $widget=shift; $this->cur->addwidget($widget); } sub description { my $this=shift; my $label=Qt::Label($this->cur->top); $label->setText("".to_Unicode($this->question->description."")); $label->show; return $label; } sub startsect { my $this = shift; my $ew = Debconf::Element::Kde::ElementWidget($this->top); $ew->init; $this->cur($ew); $this->top->addwidget($ew); $ew->show; } sub endsect { my $this = shift; $this->cur($this->top); } sub adddescription { my $this=shift; my $label=$this->description; $this->addwidget($label); } sub addhelp { my $this=shift; my $help=to_Unicode($this->question->extended_description); return unless length $help; my $label=Qt::Label($this->cur->top); $label->setText($help); $label->setWordWrap(1); $this->addwidget($label); # line1 $label->setMargin(5); $label->show; } sub value { my $this=shift; return ''; } 1 Debconf/Element/Noninteractive.pm000066600000000526150777111550013043 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Noninteractive; use strict; use base qw(Debconf::Element); sub visible { my $this=shift; return; } sub show { my $this=shift; my $default=''; $default=$this->question->value if defined $this->question->value; $this->value($default); } 1 Debconf/Element/Editor/Password.pm000066600000000253150777111550013100 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::Password; use strict; use base qw(Debconf::Element::Editor::String); 1 Debconf/Element/Editor/Multiselect.pm000066600000001624150777111550013573 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::Multiselect; use strict; use Debconf::Gettext; use base qw(Debconf::Element::Multiselect); sub show { my $this=shift; my @choices=$this->question->choices_split; $this->frontend->comment($this->question->extended_description."\n\n". "(".gettext("Choices").": ".join(", ", @choices).")\n". gettext("(Enter zero or more items separated by a comma followed by a space (', ').)")."\n". $this->question->description."\n"); $this->frontend->item($this->question->name, join ", ", $this->translate_default); } sub value { my $this=shift; return $this->SUPER::value() unless @_; my @values=split(',\s+', shift); my %valid=map { $_ => 1 } $this->question->choices_split; $this->SUPER::value(join(', ', $this->order_values( map { $this->translate_to_C($_) } grep { $valid{$_} } @values))); } 1 Debconf/Element/Editor/Error.pm000066600000000245150777111550012370 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::Error; use strict; use base qw(Debconf::Element::Editor::Text); 1 Debconf/Element/Editor/Select.pm000066600000001502150777111550012513 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::Select; use strict; use Debconf::Gettext; use base qw(Debconf::Element::Select); sub show { my $this=shift; my $default=$this->translate_default; my @choices=$this->question->choices_split; $this->frontend->comment($this->question->extended_description."\n\n". "(".gettext("Choices").": ".join(", ", @choices).")\n". $this->question->description."\n"); $this->frontend->item($this->question->name, $default); } sub value { my $this=shift; return $this->SUPER::value() unless @_; my $value=shift; my %valid=map { $_ => 1 } $this->question->choices_split; if ($valid{$value}) { return $this->SUPER::value($this->translate_to_C($value)); } else { return $this->SUPER::value($this->question->value); } } 1 Debconf/Element/Editor/String.pm000066600000000667150777111550012555 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::String; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->comment($this->question->extended_description."\n\n". $this->question->description."\n"); my $default=''; $default=$this->question->value if defined $this->question->value; $this->frontend->item($this->question->name, $default); } 1 Debconf/Element/Editor/Note.pm000066600000000244150777111550012203 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::Note; use strict; use base qw(Debconf::Element::Editor::Text); 1 Debconf/Element/Editor/Text.pm000066600000000474150777111550012227 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::Text; use strict; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->comment($this->question->extended_description."\n\n". $this->question->description."\n\n"); $this->value(''); } 1 Debconf/Element/Editor/Boolean.pm000066600000001761150777111550012662 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::Boolean; use strict; use Debconf::Gettext; use base qw(Debconf::Element); sub show { my $this=shift; $this->frontend->comment($this->question->extended_description."\n\n". "(".gettext("Choices").": ".join(", ", gettext("yes"), gettext("no")).")\n". $this->question->description."\n"); my $default=''; $default=$this->question->value if defined $this->question->value; if ($default eq 'true') { $default=gettext("yes"); } elsif ($default eq 'false') { $default=gettext("no"); } $this->frontend->item($this->question->name, $default); } sub value { my $this=shift; return $this->SUPER::value() unless @_; my $value=shift; if ($value eq 'yes' || $value eq gettext("yes")) { return $this->SUPER::value('true'); } elsif ($value eq 'no' || $value eq gettext("no")) { return $this->SUPER::value('false'); } else { return $this->SUPER::value($this->question->value); } } 1 Debconf/Element/Editor/Progress.pm000066600000000353150777111550013103 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Editor::Progress; use strict; use base qw(Debconf::Element); sub start { } sub set { return 1; } sub info { return 1; } sub stop { } 1; Debconf/Element/Gnome/Password.pm000066600000001104150777111550012713 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::Password; use strict; use Gtk2; use utf8; use base qw(Debconf::Element::Gnome); sub init { my $this=shift; $this->SUPER::init(@_); $this->adddescription; $this->widget(Gtk2::Entry->new); $this->widget->show; $this->widget->set_visibility(0); $this->addwidget($this->widget); $this->tip( $this->widget ); $this->addhelp; } sub value { my $this=shift; my $text = $this->widget->get_chars(0, -1); $text = $this->question->value if $text eq ''; return $text; } 1 Debconf/Element/Gnome/Multiselect.pm000066600000004657150777111550013423 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::Multiselect; use strict; use Gtk2; use utf8; use Debconf::Encoding qw(to_Unicode); use base qw(Debconf::Element::Gnome Debconf::Element::Multiselect); use constant SELECTED_COLUMN => 0; use constant CHOICES_COLUMN => 1; sub init { my $this=shift; my @choices = map { to_Unicode($_) } $this->question->choices_split; my %default=map { to_Unicode($_) => 1 } $this->translate_default; $this->SUPER::init(@_); $this->multiline(1); $this->adddescription; $this->widget(Gtk2::ScrolledWindow->new); $this->widget->show; $this->widget->set_policy('automatic', 'automatic'); my $list_store = Gtk2::ListStore->new('Glib::Boolean', 'Glib::String'); $this->list_view(Gtk2::TreeView->new($list_store)); $this->list_view->set_headers_visible(0); my $renderer_toggle = Gtk2::CellRendererToggle->new; $renderer_toggle->signal_connect(toggled => sub { my $path_string = $_[1]; my $model = $_[2]; my $iter = $model->get_iter_from_string($path_string); $model->set($iter, SELECTED_COLUMN, not $model->get($iter, SELECTED_COLUMN)); }, $list_store); $this->list_view->append_column( Gtk2::TreeViewColumn->new_with_attributes('Selected', $renderer_toggle, 'active', SELECTED_COLUMN)); $this->list_view->append_column( Gtk2::TreeViewColumn->new_with_attributes('Choices', Gtk2::CellRendererText->new, 'text', CHOICES_COLUMN)); $this->list_view->show; $this->widget->add($this->list_view); for (my $i=0; $i <= $#choices; $i++) { my $iter = $list_store->append(); $list_store->set($iter, CHOICES_COLUMN, $choices[$i]); if ($default{$choices[$i]}) { $list_store->set($iter, SELECTED_COLUMN, 1); } } $this->addwidget($this->widget); $this->tip($this->list_view); $this->addhelp; $this->fill(1); $this->expand(1); } sub value { my $this=shift; my $list_view = $this->list_view; my $list_store = $list_view->get_model (); my ($ret, $val); my @vals; $this->question->template->i18n(''); my @choices=$this->question->choices_split; $this->question->template->i18n(1); my $iter = $list_store->get_iter_first(); for (my $i=0; $i <= $#choices; $i++) { if ($list_store->get($iter, SELECTED_COLUMN)) { push @vals, $choices[$i]; } $iter = $list_store->iter_next($iter); } return join(', ', $this->order_values(@vals)); } *visible = \&Debconf::Element::Multiselect::visible; 1 Debconf/Element/Gnome/Error.pm000066600000002216150777111550012207 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::Error; use strict; use Debconf::Gettext; use Gtk2; use utf8; use Debconf::Encoding qw(to_Unicode); use base qw(Debconf::Element::Gnome); sub init { my $this=shift; my $extended_description = to_Unicode($this->question->extended_description); $this->SUPER::init(@_); $this->multiline(1); $this->fill(1); $this->expand(1); $this->widget(Gtk2::HBox->new(0, 0)); my $image = Gtk2::Image->new_from_stock("gtk-dialog-error", "dialog"); $image->show; my $text = Gtk2::TextView->new(); my $textbuffer = $text->get_buffer; $text->show; $text->set_wrap_mode ("word"); $text->set_editable (0); my $scrolled_window = Gtk2::ScrolledWindow->new(); $scrolled_window->show; $scrolled_window->set_policy('automatic', 'automatic'); $scrolled_window->set_shadow_type('in'); $scrolled_window->add ($text); $this->widget->show; $this->widget->pack_start($image, 0, 0, 6); $this->widget->pack_start($scrolled_window, 1, 1, 0); $textbuffer->set_text($extended_description); $this->widget->show; $this->adddescription; $this->addwidget($this->widget); } 1 Debconf/Element/Gnome/Select.pm000066600000002030150777111550012327 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::Select; use strict; use Gtk2; use Gnome2; use utf8; use Debconf::Encoding qw(to_Unicode); use base qw(Debconf::Element::Gnome Debconf::Element::Select); sub init { my $this=shift; my $default=$this->translate_default; my @choices= map { to_Unicode($_) } $this->question->choices_split; $this->SUPER::init(@_); $this->widget(Gtk2::Combo->new); $this->widget->show; $this->widget->set_popdown_strings(@choices); $this->widget->set_value_in_list(1, 0); $this->widget->entry->set_editable(0); if (defined($default) and length($default) != 0) { $this->widget->entry->set_text(to_Unicode($default)); } else { $this->widget->entry->set_text($choices[0]); } $this->adddescription; $this->addwidget($this->widget); $this->tip( $this->widget->entry ); $this->addhelp; } sub value { my $this=shift; return $this->translate_to_C_uni($this->widget->entry->get_chars(0, -1)); } *visible = \&Debconf::Element::Select::visible; 1 Debconf/Element/Gnome/String.pm000066600000001211150777111550012356 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::String; use strict; use Gtk2; use utf8; use Debconf::Encoding qw(to_Unicode); use base qw(Debconf::Element::Gnome); sub init { my $this=shift; $this->SUPER::init(@_); $this->widget(Gtk2::Entry->new); $this->widget->show; my $default=''; $default=$this->question->value if defined $this->question->value; $this->widget->set_text(to_Unicode($default)); $this->adddescription; $this->addwidget($this->widget); $this->tip( $this->widget ); $this->addhelp; } sub value { my $this=shift; return $this->widget->get_chars(0, -1); } 1 Debconf/Element/Gnome/Note.pm000066600000002064150777111550012024 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::Note; use strict; use Debconf::Gettext; use Gtk2; use utf8; use Debconf::Encoding qw(to_Unicode); use Debconf::Element::Noninteractive::Note; use base qw(Debconf::Element::Gnome); sub init { my $this=shift; my $extended_description = to_Unicode($this->question->extended_description); $this->SUPER::init(@_); $this->multiline(1); $this->fill(1); $this->expand(1); $this->widget(Gtk2::HBox->new(0, 0)); my $text = Gtk2::TextView->new(); my $textbuffer = $text->get_buffer; $text->show; $text->set_wrap_mode ("word"); $text->set_editable (0); my $scrolled_window = Gtk2::ScrolledWindow->new(); $scrolled_window->show; $scrolled_window->set_policy('automatic', 'automatic'); $scrolled_window->set_shadow_type('in'); $scrolled_window->add ($text); $this->widget->show; $this->widget->pack_start($scrolled_window, 1, 1, 0); $textbuffer->set_text($extended_description); $this->widget->show; $this->adddescription; $this->addwidget($this->widget); } 1 Debconf/Element/Gnome/Text.pm000066600000000454150777111550012044 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::Text; use strict; use Debconf::Gettext; use Gtk2; use utf8; use base qw(Debconf::Element::Gnome); sub init { my $this=shift; $this->SUPER::init(@_); $this->adddescription; # yeah, that's all } 1 Debconf/Element/Gnome/Boolean.pm000066600000001254150777111550012476 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::Boolean; use strict; use Gtk2; use utf8; use Debconf::Encoding qw(to_Unicode); use base qw(Debconf::Element::Gnome); sub init { my $this=shift; my $description=to_Unicode($this->question->description); $this->SUPER::init(@_); $this->widget(Gtk2::CheckButton->new($description)); $this->widget->show; $this->widget->set_active(($this->question->value eq 'true') ? 1 : 0); $this->addwidget($this->widget); $this->tip( $this->widget ); $this->addhelp; } sub value { my $this=shift; if ($this->widget->get_active) { return "true"; } else { return "false"; } } 1 Debconf/Element/Gnome/Progress.pm000066600000002131150777111550012716 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Element::Gnome::Progress; use strict; use Gtk2; use utf8; use Debconf::Encoding qw(to_Unicode); use base qw(Debconf::Element::Gnome); sub _fraction { my $this=shift; return (($this->progress_cur() - $this->progress_min()) / ($this->progress_max() - $this->progress_min())); } sub start { my $this=shift; my $description=to_Unicode($this->question->description); my $frontend=$this->frontend; $this->SUPER::init(@_); $this->multiline(1); $this->expand(1); $frontend->title($description); $this->widget(Gtk2::ProgressBar->new()); $this->widget->show; $this->widget->set_text(' '); $this->addwidget($this->widget); $this->addhelp; } sub set { my $this=shift; my $value=shift; $this->progress_cur($value); $this->widget->set_fraction($this->_fraction); return 1; } sub info { my $this=shift; my $question=shift; $this->widget->set_text(to_Unicode($question->description)); return 1; } sub stop { my $this=shift; my $frontend=$this->frontend; $frontend->title($frontend->requested_title); } 1; Debconf/Config.pm000066600000015550150777111550007672 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Config; use strict; use Debconf::Question; use Debconf::Gettext; use Debconf::Priority qw(priority_valid priority_list); use Debconf::Log qw(warn); use Debconf::Db; use fields qw(config templates frontend frontend_forced priority terse reshow admin_email log debug nowarnings smileys sigils noninteractive_seen c_values); our $config=fields::new('Debconf::Config'); our @config_files=("/etc/debconf.conf", "/usr/share/debconf/debconf.conf"); if ($ENV{DEBCONF_SYSTEMRC}) { unshift @config_files, $ENV{DEBCONF_SYSTEMRC}; } else { unshift @config_files, ((getpwuid($>))[7])."/.debconfrc"; } sub _hashify ($$) { my $text=shift; my $hash=shift; $text =~ s/\${([^}]+)}/$ENV{$1}/eg; my %ret; my $i; foreach my $line (split /\n/, $text) { next if $line=~/^\s*#/; # comment next if $line=~/^\s*$/; # blank $line=~s/^\s+//; $line=~s/\s+$//; $i++; my ($key, $value)=split(/\s*:\s*/, $line, 2); $key=~tr/-/_/; die "Parse error" unless defined $key and length $key; $hash->{lc($key)}=$value; } return $i; } sub _env_to_driver { my $value=shift; my ($name, $options) = $value =~ m/^(\w+)(?:{(.*)})?$/; return unless $name; return $name if Debconf::DbDriver->driver($name); my %hash = @_; # defaults from params $hash{driver} = $name; if (defined $options) { foreach (split ' ', $options) { if (/^(\w+):(.*)/) { $hash{$1}=$2; } else { $hash{filename}=$_; } } } return Debconf::Db->makedriver(%hash)->{name}; } sub load { my $class=shift; my $cf=shift; my @defaults=@_; if (! $cf) { for my $file (@config_files) { $cf=$file, last if -e $file; } } die "No config file found" unless $cf; open (DEBCONF_CONFIG, $cf) or die "$cf: $!\n"; local $/="\n\n"; # read a stanza at a time 1 until _hashify(, $config) || eof DEBCONF_CONFIG; if (! exists $config->{config}) { print STDERR "debconf: ".gettext("Config database not specified in config file.")."\n"; exit(1); } if (! exists $config->{templates}) { print STDERR "debconf: ".gettext("Template database not specified in config file.")."\n"; exit(1); } if (exists $config->{sigils} || exists $config->{smileys}) { print STDERR "debconf: ".gettext("The Sigils and Smileys options in the config file are no longer used. Please remove them.")."\n"; } while () { my %config=(@defaults); if (exists $ENV{DEBCONF_DB_REPLACE}) { $config{readonly} = "true"; } next unless _hashify($_, \%config); eval { Debconf::Db->makedriver(%config); }; if ($@) { print STDERR "debconf: ".sprintf(gettext("Problem setting up the database defined by stanza %s of %s."),$., $cf)."\n"; die $@; } } close DEBCONF_CONFIG; if (exists $ENV{DEBCONF_DB_REPLACE}) { $config->{config} = _env_to_driver($ENV{DEBCONF_DB_REPLACE}, name => "_ENV_REPLACE"); Debconf::Db->makedriver( driver => "Pipe", name => "_ENV_REPLACE_templates", infd => "none", outfd => "none", ); my @template_stack = ("_ENV_REPLACE_templates", $config->{templates}); Debconf::Db->makedriver( driver => "Stack", name => "_ENV_stack_templates", stack => join(", ", @template_stack), ); $config->{templates} = "_ENV_stack_templates"; } my @finalstack = ($config->{config}); if (exists $ENV{DEBCONF_DB_OVERRIDE}) { unshift @finalstack, _env_to_driver($ENV{DEBCONF_DB_OVERRIDE}, name => "_ENV_OVERRIDE"); } if (exists $ENV{DEBCONF_DB_FALLBACK}) { push @finalstack, _env_to_driver($ENV{DEBCONF_DB_FALLBACK}, name => "_ENV_FALLBACK", readonly => "true"); } if (@finalstack > 1) { Debconf::Db->makedriver( driver => "Stack", name => "_ENV_stack", stack => join(", ", @finalstack), ); $config->{config} = "_ENV_stack"; } } sub getopt { my $class=shift; my $usage=shift; my $showusage=sub { # closure print STDERR $usage."\n"; print STDERR gettext(<frontend(shift); $config->frontend_forced(1) }, 'priority|p=s', sub { shift; $class->priority(shift) }, 'terse', sub { $config->{terse} = 'true' }, 'help|h', $showusage, @_, ) || $showusage->(); } sub frontend { my $class=shift; return $ENV{DEBIAN_FRONTEND} if exists $ENV{DEBIAN_FRONTEND}; $config->{frontend}=shift if @_; return $config->{frontend} if exists $config->{frontend}; my $ret='dialog'; my $question=Debconf::Question->get('debconf/frontend'); if ($question) { $ret=lcfirst($question->value) || $ret; } return $ret; } sub frontend_forced { my ($class, $val) = @_; $config->{frontend_forced} = $val if defined $val || exists $ENV{DEBIAN_FRONTEND}; return $config->{frontend_forced} ? 1 : 0; } sub priority { my $class=shift; return $ENV{DEBIAN_PRIORITY} if exists $ENV{DEBIAN_PRIORITY}; if (@_) { my $newpri=shift; if (! priority_valid($newpri)) { warn(sprintf(gettext("Ignoring invalid priority \"%s\""), $newpri)); warn(sprintf(gettext("Valid priorities are: %s"), join(" ", priority_list))); } else { $config->{priority}=$newpri; } } return $config->{priority} if exists $config->{priority}; my $ret='high'; my $question=Debconf::Question->get('debconf/priority'); if ($question) { $ret=$question->value || $ret; } return $ret; } sub terse { my $class=shift; return $ENV{DEBCONF_TERSE} if exists $ENV{DEBCONF_TERSE}; $config->{terse}=$_[0] if @_; return $config->{terse} if exists $config->{terse}; return 'false'; } sub nowarnings { my $class=shift; return $ENV{DEBCONF_NOWARNINGS} if exists $ENV{DEBCONF_NOWARNINGS}; $config->{nowarnings}=$_[0] if @_; return $config->{nowarnings} if exists $config->{nowarnings}; return 'false'; } sub debug { my $class=shift; return $ENV{DEBCONF_DEBUG} if exists $ENV{DEBCONF_DEBUG}; return $config->{debug} if exists $config->{debug}; return ''; } sub admin_email { my $class=shift; return $ENV{DEBCONF_ADMIN_EMAIL} if exists $ENV{DEBCONF_ADMIN_EMAIL}; return $config->{admin_email} if exists $config->{admin_email}; return 'root'; } sub noninteractive_seen { my $class=shift; return $ENV{DEBCONF_NONINTERACTIVE_SEEN} if exists $ENV{DEBCONF_NONINTERACTIVE_SEEN}; return $config->{noninteractive_seen} if exists $config->{noninteractive_seen}; return 'false'; } sub c_values { my $class=shift; return $ENV{DEBCONF_C_VALUES} if exists $ENV{DEBCONF_C_VALUES}; return $config->{c_values} if exists $config->{c_values}; return 'false'; } sub AUTOLOAD { (my $field = our $AUTOLOAD) =~ s/.*://; my $class=shift; return $config->{$field}=shift if @_; return $config->{$field} if defined $config->{$field}; return ''; } 1 Debconf/AutoSelect.pm000066600000003451150777111550010532 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::AutoSelect; use strict; use Debconf::Gettext; use Debconf::ConfModule; use Debconf::Config; use Debconf::Log qw(:all); use base qw(Exporter); our @EXPORT_OK = qw(make_frontend make_confmodule); our %EXPORT_TAGS = (all => [@EXPORT_OK]); my %fallback=( 'Kde' => ['Dialog', 'Readline', 'Teletype'], 'Gnome' => ['Dialog', 'Readline', 'Teletype'], 'Web' => ['Dialog', 'Readline', 'Teletype'], 'Dialog' => ['Readline', 'Teletype'], 'Gtk' => ['Dialog', 'Readline', 'Teletype'], 'Readline' => ['Teletype', 'Dialog'], 'Editor' => ['Readline', 'Teletype'], 'Slang' => ['Dialog', 'Readline', 'Teletype'], 'Text' => ['Readline', 'Teletype', 'Dialog'], ); my $frontend; my $type; sub make_frontend { my $script=shift; my $starttype=ucfirst($type) if defined $type; if (! defined $starttype || ! length $starttype) { $starttype = Debconf::Config->frontend; if ($starttype =~ /^[A-Z]/) { warn "Please do not capitalize the first letter of the debconf frontend."; } $starttype=ucfirst($starttype); } my $showfallback=0; foreach $type ($starttype, @{$fallback{$starttype}}, 'Noninteractive') { if (! $showfallback) { debug user => "trying frontend $type"; } else { warn(sprintf(gettext("falling back to frontend: %s"), $type)); } $frontend=eval qq{ use Debconf::FrontEnd::$type; Debconf::FrontEnd::$type->new(); }; return $frontend if defined $frontend; warn sprintf(gettext("unable to initialize frontend: %s"), $type); $@=~s/\n.*//s; warn "($@)"; $showfallback=1; } die sprintf(gettext("Unable to start a frontend: %s"), $@); } sub make_confmodule { my $confmodule=Debconf::ConfModule->new(frontend => $frontend); $confmodule->startup(@_) if @_; return $confmodule; } 1 Debconf/Client/ConfModule.pm000066600000007474150777111550011744 0ustar00#!/usr/bin/perl -w =head1 NAME Debconf::Client::ConfModule - client module for ConfModules =head1 SYNOPSIS use Debconf::Client::ConfModule ':all'; version('2.0'); my $capb=capb('backup'); input("medium", "foo/bar"); my @ret=go(); if ($ret[0] == 30) { # Back button pressed. ... } ... =head1 DESCRIPTION This is a module to ease writing ConfModules for Debian's configuration management system. It can communicate with a FrontEnd via the debconf protocol (which is documented in full in the debconf_specification in Debian policy). The design is that each command in the protocol is represented by one function in this module (with the name lower-cased). Call the function and pass in any parameters you want to follow the command. If the function is called in scalar context, it will return any textual return code. If it is called in list context, an array consisting of the numeric return code and the textual return code will be returned. This module uses Exporter to export all functions it defines. To import everything, simply import ":all". =over 4 =cut package Debconf::Client::ConfModule; use strict; use base qw(Exporter); # List all valid commands here. our @EXPORT_OK=qw(version capb stop reset title input beginblock endblock go unset set get register unregister clear previous_module start_frontend fset fget subst purge metaget visible exist settitle info progress data x_loadtemplatefile); # Import :all to get everything. our %EXPORT_TAGS = (all => [@EXPORT_OK]); # Set up valid command lookup hash. my %commands; map { $commands{uc $_}=1; } @EXPORT_OK; # Unbuffered output is required. $|=1; =item import Ensure that a FrontEnd is running. It's a little hackish. If DEBIAN_HAS_FRONTEND is set, a FrontEnd is assumed to be running. If not, one is started up automatically and stdin and out are connected to it. Note that this function is always run when the module is loaded in the usual way. =cut sub import { if (! $ENV{DEBIAN_HAS_FRONTEND}) { $ENV{PERL_DL_NONLAZY}=1; if (exists $ENV{DEBCONF_USE_CDEBCONF} and $ENV{DEBCONF_USE_CDEBCONF} ne '') { exec "/usr/lib/cdebconf/debconf", $0, @ARGV; } else { exec "/usr/share/debconf/frontend", $0, @ARGV; } } # Make the Exporter still work. Debconf::Client::ConfModule->export_to_level(1, @_); # A truly gross hack. This is only needed if # /usr/share/debconf/confmodule is loaded, and then this # perl module is used. In that case, this module needs to write # to fd #3, rather than stdout. See changelog 0.3.74. if (exists $ENV{DEBCONF_REDIR} && $ENV{DEBCONF_REDIR}) { open(STDOUT,">&3"); } } =item stop The frontend doesn't send a return code here, so we cannot try to read it or we'll block. =cut sub stop { print "STOP\n"; return; } =item AUTOLOAD Creates handler functions for commands on the fly. =cut sub AUTOLOAD { my $command = uc our $AUTOLOAD; $command =~ s|.*:||; # strip fully-qualified portion die "Unsupported command `$command'." unless $commands{$command}; no strict 'refs'; *$AUTOLOAD = sub { my $c=join (' ', $command, @_); # Newlines in input can really badly confuse the protocol, so # detect and warn. if ($c=~m/\n/) { warn "Warning: Newline present in parameters passed to debconf.\n"; warn "This will probably cause strange things to happen!\n"; } print "$c\n"; my $ret=; chomp $ret; my @ret=split(/\s/, $ret, 2); if ($ret[0] eq '1') { # escaped data local $_; my $unescaped=''; for (split /(\\.)/, $ret[1]) { s/\\(.)/$1 eq "n" ? "\n" : $1/eg; $unescaped.=$_; } $ret[0]='0'; $ret[1]=$unescaped; } return @ret if wantarray; return $ret[1]; }; goto &$AUTOLOAD; } =back =head1 SEE ALSO The debconf specification (/usr/share/doc/debian-policy/debconf_specification.txt.gz). =head1 AUTHOR Joey Hess =cut 1 Debconf/Gettext.pm000066600000000455150777111550010107 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Gettext; use strict; BEGIN { eval 'use Locale::gettext'; if ($@) { eval q{ sub gettext { return shift; } }; } else { textdomain('debconf'); } } use base qw(Exporter); our @EXPORT=qw(gettext); 1 Debconf/Base.pm000066600000000763150777111550007337 0ustar00#!/usr/bin/perl -w # This file was preprocessed, do not edit! package Debconf::Base; use Debconf::Log ':all'; use strict; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $this=bless ({@_}, $class); $this->init; return $this; } sub init {} sub AUTOLOAD { (my $field = our $AUTOLOAD) =~ s/.*://; no strict 'refs'; *$AUTOLOAD = sub { my $this=shift; return $this->{$field} unless @_; return $this->{$field}=shift; }; goto &$AUTOLOAD; } sub DESTROY { } 1 Text/WrapI18N.pm000066600000014362150777111550007362 0ustar00package Text::WrapI18N; require Exporter; use strict; use warnings; our @ISA = qw(Exporter); our @EXPORT = qw(wrap); our @EXPORT_OK = qw($columns $separator); our %EXPORT_TAGS = ('all' => [ @EXPORT, @EXPORT_OK ]); our $VERSION = '0.06'; use vars qw($columns $break $tabstop $separator $huge $unexpand $charmap); use Text::CharWidth qw(mbswidth mblen); BEGIN { $columns = 76; # $break, $separator, $huge, and $unexpand are not supported yet. $break = '\s'; $tabstop = 8; $separator = "\n"; $huge = 'wrap'; $unexpand = 1; undef $charmap; } sub wrap { my $top1=shift; my $top2=shift; my $text=shift; $text = $top1 . $text; # $out already-formatted text for output including current line # $len visible width of the current line without the current word # $word the current word which might be sent to the next line # $wlen visible width of the current word # $c the current character # $b whether to allow line-breaking after the current character # $cont_lf true when LF (line feed) characters appear continuously # $w visible width of the current character my $out = ''; my $len = 0; my $word = ''; my $wlen = 0; my $cont_lf = 0; my ($c, $w, $b); $text =~ s/\n+$/\n/; while(1) { if (length($text) == 0) { return $out . $word; } ($c, $text, $w, $b) = _extract($text); if ($c eq "\n") { $out .= $word . $separator; if (length($text) == 0) {return $out;} $len = 0; $text = $top2 . $text; $word = '' ; $wlen = 0; next; } elsif ($w == -1) { # all control characters other than LF are ignored next; } # when the current line have enough room # for the curren character if ($len + $wlen + $w <= $columns) { if ($c eq ' ' || $b) { $out .= $word . $c; $len += $wlen + $w; $word = ''; $wlen = 0; } else { $word .= $c; $wlen += $w; } next; } # when the current line overflows with the # current character if ($c eq ' ') { # the line ends by space $out .= $word . $separator; $len = 0; $text = $top2 . $text; $word = ''; $wlen = 0; } elsif ($wlen + $w <= $columns - length ($top2)) { # the current word is sent to next line $out .= $separator; $len = 0; $text = $top2 . $word . $c . $text; $word = ''; $wlen = 0; } else { # the current word is too long to fit a line $out .= $word . $separator; $len = 0; $text = $top2 . $c . $text; $word = ''; $wlen = 0; } } } # Extract one character from the beginning from the given string. # Supports multibyte encodings such as UTF-8, EUC-JP, EUC-KR, # GB2312, and Big5. # # return value: (character, rest string, width, line breakable) # character: a character. This may consist from multiple bytes. # rest string: given string without the extracted character. # width: number of columns which the character occupies on screen. # line breakable: true if the character allows line break after it. sub _extract { my $string=shift; my ($l, $c, $r, $w, $b, $u); if (length($string) == 0) { return ('', '', 0, 0); } $l = mblen($string); if ($l == 0 || $l == -1) { return ('?', substr($string,1), 1, 0); } $c = substr($string, 0, $l); $r = substr($string, $l); $w = mbswidth($c); if (!defined($charmap)) { $charmap = `/usr/bin/locale charmap`; } if ($charmap =~ /UTF.8/i) { # UTF-8 if ($l == 3) { # U+0800 - U+FFFF $u = (ord(substr($c,0,1))&0x0f) * 0x1000 + (ord(substr($c,1,1))&0x3f) * 0x40 + (ord(substr($c,2,1))&0x3f); $b = _isCJ($u); } elsif ($l == 4) { # U+10000 - U+10FFFF $u = (ord(substr($c,0,1))&7) * 0x40000 + (ord(substr($c,1,1))&0x3f) * 0x1000 + (ord(substr($c,2,1))&0x3f) * 0x40 + (ord(substr($c,3,1))&0x3f); $b = _isCJ($u); } else { $b = 0; } } elsif ($charmap =~ /(^EUC)|(^GB)|(^BIG)/i) { # East Asian legacy encodings # (EUC-JP, EUC-KR, GB2312, Big5, Big5HKSCS, and so on) if (ord(substr($c,0,1)) >= 0x80) {$b = 1;} else {$b = 0;} } else { $b = 0; } return ($c, $r, $w, $b); } # Returns 1 for Chinese and Japanese characters. This means that # these characters allow line wrapping after this character even # without whitespaces because these languages don't use whitespaces # between words. # # Character must be given in UCS-4 codepoint value. sub _isCJ { my $u=shift; if ($u >= 0x3000 && $u <= 0x312f) { if ($u == 0x300a || $u == 0x300c || $u == 0x300e || $u == 0x3010 || $u == 0x3014 || $u == 0x3016 || $u == 0x3018 || $u == 0x301a) {return 0;} return 1; } # CJK punctuations, Hiragana, Katakana, Bopomofo if ($u >= 0x31a0 && $u <= 0x31bf) {return 1;} # Bopomofo if ($u >= 0x31f0 && $u <= 0x31ff) {return 1;} # Katakana extension if ($u >= 0x3400 && $u <= 0x9fff) {return 1;} # Han Ideogram if ($u >= 0xf900 && $u <= 0xfaff) {return 1;} # Han Ideogram if ($u >= 0x20000 && $u <= 0x2ffff) {return 1;} # Han Ideogram return 0; } 1; __END__ =head1 NAME Text::WrapI18N - Line wrapping module with support for multibyte, fullwidth, and combining characters and languages without whitespaces between words =head1 SYNOPSIS use Text::WrapI18N qw(wrap $columns); wrap(firstheader, nextheader, texts); =head1 DESCRIPTION This module intends to be a better Text::Wrap module. This module is needed to support multibyte character encodings such as UTF-8, EUC-JP, EUC-KR, GB2312, and Big5. This module also supports characters with irregular widths, such as combining characters (which occupy zero columns on terminal, like diacritical marks in UTF-8) and fullwidth characters (which occupy two columns on terminal, like most of east Asian characters). Also, minimal handling of languages which doesn't use whitespaces between words (like Chinese and Japanese) is supported. Like Text::Wrap, hyphenation and "kinsoku" processing are not supported, to keep simplicity. I is the main subroutine of Text::WrapI18N module to execute the line wrapping. Input parameters and output data emulate Text::Wrap. The texts have to be written in locale encoding. =head1 SEE ALSO locale(5), utf-8(7), charsets(7) =head1 AUTHOR Tomohiro KUBOTA, Ekubota@debian.orgE =head1 COPYRIGHT AND LICENSE Copyright 2003 by Tomohiro KUBOTA This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Date/Language.pm000066600000005110150777111550007514 0ustar00 package Date::Language; use strict; use Time::Local; use Carp; use vars qw($VERSION @ISA); require Date::Format; $VERSION = "1.10"; @ISA = qw(Date::Format::Generic); sub new { my $self = shift; my $type = shift || $self; $type =~ s/^(\w+)$/Date::Language::$1/; croak "Bad language" unless $type =~ /^[\w:]+$/; eval "require $type" or croak $@; bless [], $type; } # Stop AUTOLOAD being called ;-) sub DESTROY {} sub AUTOLOAD { use vars qw($AUTOLOAD); if($AUTOLOAD =~ /::strptime\Z/o) { my $self = $_[0]; my $type = ref($self) || $self; require Date::Parse; no strict 'refs'; *{"${type}::strptime"} = Date::Parse::gen_parser( \%{"${type}::DoW"}, \%{"${type}::MoY"}, \@{"${type}::Dsuf"}, 1); goto &{"${type}::strptime"}; } croak "Undefined method &$AUTOLOAD called"; } sub str2time { my $me = shift; my @t = $me->strptime(@_); return undef unless @t; my($ss,$mm,$hh,$day,$month,$year,$zone) = @t; my @lt = localtime(time); $hh ||= 0; $mm ||= 0; $ss ||= 0; $month = $lt[4] unless(defined $month); $day = $lt[3] unless(defined $day); $year = ($month > $lt[4]) ? ($lt[5] - 1) : $lt[5] unless(defined $year); return defined $zone ? timegm($ss,$mm,$hh,$day,$month,$year) - $zone : timelocal($ss,$mm,$hh,$day,$month,$year); } 1; __END__ =head1 NAME Date::Language - Language specific date formating and parsing =head1 SYNOPSIS use Date::Language; my $lang = Date::Language->new('German'); $lang->time2str("%a %b %e %T %Y\n", time); =head1 DESCRIPTION L provides objects to parse and format dates for specific languages. Available languages are Afar French Russian_cp1251 Amharic Gedeo Russian_koi8r Austrian German Sidama Brazilian Greek Somali Chinese Hungarian Spanish Chinese_GB Icelandic Swedish Czech Italian Tigrinya Danish Norwegian TigrinyaEritrean Dutch Oromo TigrinyaEthiopian English Romanian Turkish Finnish Russian =head1 METHODS =over =item time2str See L =item strftime See L =item ctime See L =item asctime See L =item str2time See L =item strptime See L =back Date/Format.pm000066600000022660150777111550007232 0ustar00# Copyright (c) 1995-2009 Graham Barr. This program is free # software; you can redistribute it and/or modify it under the same terms # as Perl itself. package Date::Format; use strict; use vars qw(@EXPORT @ISA $VERSION); require Exporter; $VERSION = "2.24"; @ISA = qw(Exporter); @EXPORT = qw(time2str strftime ctime asctime); sub time2str ($;$$) { Date::Format::Generic->time2str(@_); } sub strftime ($\@;$) { Date::Format::Generic->strftime(@_); } sub ctime ($;$) { my($t,$tz) = @_; Date::Format::Generic->time2str("%a %b %e %T %Y\n", $t, $tz); } sub asctime (\@;$) { my($t,$tz) = @_; Date::Format::Generic->strftime("%a %b %e %T %Y\n", $t, $tz); } ## ## ## package Date::Format::Generic; use vars qw($epoch $tzname); use Time::Zone; use Time::Local; sub ctime { my($me,$t,$tz) = @_; $me->time2str("%a %b %e %T %Y\n", $t, $tz); } sub asctime { my($me,$t,$tz) = @_; $me->strftime("%a %b %e %T %Y\n", $t, $tz); } sub _subs { my $fn; $_[1] =~ s/ %(O?[%a-zA-Z]) / ($_[0]->can("format_$1") || sub { $1 })->($_[0]); /sgeox; $_[1]; } sub strftime { my($pkg,$fmt,$time); ($pkg,$fmt,$time,$tzname) = @_; my $me = ref($pkg) ? $pkg : bless []; if(defined $tzname) { $tzname = uc $tzname; $tzname = sprintf("%+05d",$tzname) unless($tzname =~ /\D/); $epoch = timegm(@{$time}[0..5]); @$me = gmtime($epoch + tz_offset($tzname) - tz_offset()); } else { @$me = @$time; undef $epoch; } _subs($me,$fmt); } sub time2str { my($pkg,$fmt,$time); ($pkg,$fmt,$time,$tzname) = @_; my $me = ref($pkg) ? $pkg : bless [], $pkg; $epoch = $time; if(defined $tzname) { $tzname = uc $tzname; $tzname = sprintf("%+05d",$tzname) unless($tzname =~ /\D/); $time += tz_offset($tzname); @$me = gmtime($time); } else { @$me = localtime($time); } $me->[9] = $time; _subs($me,$fmt); } my(@DoW,@MoY,@DoWs,@MoYs,@AMPM,%format,@Dsuf); @DoW = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday); @MoY = qw(January February March April May June July August September October November December); @DoWs = map { substr($_,0,3) } @DoW; @MoYs = map { substr($_,0,3) } @MoY; @AMPM = qw(AM PM); @Dsuf = (qw(th st nd rd th th th th th th)) x 3; @Dsuf[11,12,13] = qw(th th th); @Dsuf[30,31] = qw(th st); %format = ('x' => "%m/%d/%y", 'C' => "%a %b %e %T %Z %Y", 'X' => "%H:%M:%S", ); my @locale; my $locale = "/usr/share/lib/locale/LC_TIME/default"; local *LOCALE; if(open(LOCALE,"$locale")) { chop(@locale = ); close(LOCALE); @MoYs = @locale[0 .. 11]; @MoY = @locale[12 .. 23]; @DoWs = @locale[24 .. 30]; @DoW = @locale[31 .. 37]; @format{"X","x","C"} = @locale[38 .. 40]; @AMPM = @locale[41 .. 42]; } sub wkyr { my($wstart, $wday, $yday) = @_; $wday = ($wday + 7 - $wstart) % 7; return int(($yday - $wday + 13) / 7 - 1); } ## ## these 6 formatting routins need to be *copied* into the language ## specific packages ## my @roman = ('',qw(I II III IV V VI VII VIII IX)); sub roman { my $n = shift; $n =~ s/(\d)$//; my $r = $roman[ $1 ]; if($n =~ s/(\d)$//) { (my $t = $roman[$1]) =~ tr/IVX/XLC/; $r = $t . $r; } if($n =~ s/(\d)$//) { (my $t = $roman[$1]) =~ tr/IVX/CDM/; $r = $t . $r; } if($n =~ s/(\d)$//) { (my $t = $roman[$1]) =~ tr/IVX/M../; $r = $t . $r; } $r; } sub format_a { $DoWs[$_[0]->[6]] } sub format_A { $DoW[$_[0]->[6]] } sub format_b { $MoYs[$_[0]->[4]] } sub format_B { $MoY[$_[0]->[4]] } sub format_h { $MoYs[$_[0]->[4]] } sub format_p { $_[0]->[2] >= 12 ? $AMPM[1] : $AMPM[0] } sub format_P { lc($_[0]->[2] >= 12 ? $AMPM[1] : $AMPM[0]) } sub format_d { sprintf("%02d",$_[0]->[3]) } sub format_e { sprintf("%2d",$_[0]->[3]) } sub format_H { sprintf("%02d",$_[0]->[2]) } sub format_I { sprintf("%02d",$_[0]->[2] % 12 || 12)} sub format_j { sprintf("%03d",$_[0]->[7] + 1) } sub format_k { sprintf("%2d",$_[0]->[2]) } sub format_l { sprintf("%2d",$_[0]->[2] % 12 || 12)} sub format_L { $_[0]->[4] + 1 } sub format_m { sprintf("%02d",$_[0]->[4] + 1) } sub format_M { sprintf("%02d",$_[0]->[1]) } sub format_q { sprintf("%01d",int($_[0]->[4] / 3) + 1) } sub format_s { $epoch = timelocal(@{$_[0]}[0..5]) unless defined $epoch; sprintf("%d",$epoch) } sub format_S { sprintf("%02d",$_[0]->[0]) } sub format_U { wkyr(0, $_[0]->[6], $_[0]->[7]) } sub format_w { $_[0]->[6] } sub format_W { wkyr(1, $_[0]->[6], $_[0]->[7]) } sub format_y { sprintf("%02d",$_[0]->[5] % 100) } sub format_Y { sprintf("%04d",$_[0]->[5] + 1900) } sub format_Z { my $o = tz_local_offset(timelocal(@{$_[0]}[0..5])); defined $tzname ? $tzname : uc tz_name($o, $_[0]->[8]); } sub format_z { my $t = timelocal(@{$_[0]}[0..5]); my $o = defined $tzname ? tz_offset($tzname, $t) : tz_offset(undef,$t); sprintf("%+03d%02d", int($o / 3600), int(abs($o) % 3600) / 60); } sub format_c { &format_x . " " . &format_X } sub format_D { &format_m . "/" . &format_d . "/" . &format_y } sub format_r { &format_I . ":" . &format_M . ":" . &format_S . " " . &format_p } sub format_R { &format_H . ":" . &format_M } sub format_T { &format_H . ":" . &format_M . ":" . &format_S } sub format_t { "\t" } sub format_n { "\n" } sub format_o { sprintf("%2d%s",$_[0]->[3],$Dsuf[$_[0]->[3]]) } sub format_x { my $f = $format{'x'}; _subs($_[0],$f); } sub format_X { my $f = $format{'X'}; _subs($_[0],$f); } sub format_C { my $f = $format{'C'}; _subs($_[0],$f); } sub format_Od { roman(format_d(@_)) } sub format_Oe { roman(format_e(@_)) } sub format_OH { roman(format_H(@_)) } sub format_OI { roman(format_I(@_)) } sub format_Oj { roman(format_j(@_)) } sub format_Ok { roman(format_k(@_)) } sub format_Ol { roman(format_l(@_)) } sub format_Om { roman(format_m(@_)) } sub format_OM { roman(format_M(@_)) } sub format_Oq { roman(format_q(@_)) } sub format_Oy { roman(format_y(@_)) } sub format_OY { roman(format_Y(@_)) } sub format_G { int(($_[0]->[9] - 315993600) / 604800) } 1; __END__ =head1 NAME Date::Format - Date formating subroutines =head1 SYNOPSIS use Date::Format; @lt = localtime(time); print time2str($template, time); print strftime($template, @lt); print time2str($template, time, $zone); print strftime($template, @lt, $zone); print ctime(time); print asctime(@lt); print ctime(time, $zone); print asctime(@lt, $zone); =head1 DESCRIPTION This module provides routines to format dates into ASCII strings. They correspond to the C library routines C and C. =over 4 =item time2str(TEMPLATE, TIME [, ZONE]) C converts C