# cpan-upload - upload one or more file to CPAN (via PAUSE) # # $Id: cpan-upload,v 2.2 2002/07/02 21:44:10 neilb Exp $ # use perl5:AppConfig::Std; use perl5:Net::FTP; use perl5:HTTP::Request::Common; use perl5:LWP::UserAgent; use perl5:HTTP::Status; use perl5:File::Basename; #----------------------------------------------------------------------- # Configuration constants and globals #----------------------------------------------------------------------- my $PROGRAM; my $SITE = 'pause.perl.org'; my $UPLOAD_DIR = 'incoming'; my $PAUSE_ADD_URI = 'http://pause.perl.org/pause/authenquery'; my $config; my @uploaded_files; our &POST := HTTP::Request::Common.can('POST'); our &basename := File::Basename.can('basename'); #----------------------------------------------------------------------- # MAIN BODY #----------------------------------------------------------------------- my $VERSION = "Pugs $?PUGS_VERSION"; initialise(); @uploaded_files = ftp_upload_files(@*ARGS); pause_add_files(@uploaded_files) if @uploaded_files > 0; _verbose(int(@*ARGS), int(@*ARGS) == 1 ?? " file " !! " files ", "uploaded successfully.\n"); exit 0; #======================================================================= # # initialise() # # Create AppConfig instance, parse config file if there is one, # and command-line options. # #======================================================================= sub initialise () { my $config_file; my $HOME; my $password; ($PROGRAM = $*PROGRAM_NAME) ~~ s:P5{^.*/}{}; #------------------------------------------------------------------- # Create an AppConfig::Std object, and define our interface # The EXPAND flag on password tells AppConfig not to try and # expand any embedded variables - eg if you have a $ sign # in your password. #------------------------------------------------------------------- $HOME = %*ENV; $config_file = "$HOME/.pause"; $config = eval(q! my $config = AppConfig::Std->new(); $config->define('user'); $config->define('directory', {ARGCOUNT => 1, ALIAS => 'dir'}); $config->define('password', { EXPAND => 0 }); $config->define('mailto'); $config->define('ftp_gateway'); $config->define('ftp_proxy'); $config->define('http_proxy'); $config->define('non_interactive', { ALIAS => 'ni', ARGCOUNT => 0 }); $config; !, :lang); #------------------------------------------------------------------- # Read the user's config file, if they have one, # then parse the command-line. #------------------------------------------------------------------- if ($config_file ~~ :f) { $config.file($config_file) || exit 1; } $config.args(\@*ARGS) || die "run \"$PROGRAM -help\" to see valid options\n"; #------------------------------------------------------------------- # Check we have the information we need #------------------------------------------------------------------- die "No files specified for upload\n" unless @*ARGS > 0; die "No email address (mailto) specified\n" unless $config.mailto; die "No PAUSE user specified\n" unless $config.user; $config.verbose(1) if $config.debug && !$config.verbose; #------------------------------------------------------------------- # Display banner at the start of the run #------------------------------------------------------------------- _verbose("$PROGRAM v$VERSION\n"); } #======================================================================= # # ftp_upload_files() # # upload the one or more files to PAUSE ftp server. # return a list of the files that were successfully uploaded. # #======================================================================= sub ftp_upload_files (*@files) { my @uploaded = (); # list of files actually uploaded my $ftp; # Net::FTP instance my @new_args; # arg list to pass to constructor my ($user, $password); # user and password for login method my $file; _verbose("Using FTP to upload files to PAUSE\n"); #------------------------------------------------------------------- # Make the connection to the PAUSE ftp server: # First we determine how we're going to make the connection ... #------------------------------------------------------------------- if $config.ftp_gateway { _debug(" establishing connection via an FTP gateway\n"); @new_args = ($config.ftp_gateway); ($user, $password) = ("ftp\@$SITE", $config.mailto); } else { ($user, $password) = ('ftp', $config.mailto); @new_args = ($SITE); if $config.ftp_proxy { _debug(" establishing connection via proxy", $config.ftp_proxy, "\n"); push(@new_args, Firewall => $config.ftp_proxy); } else { _debug(" establishing connection\n"); } } #------------------------------------------------------------------- # ... and then we actually make the connection and log in #------------------------------------------------------------------- $ftp = Net::FTP.new([,] @new_args); if (!$ftp) { die "failed to connect to remote server: $!\n"; } if (!$ftp.login($user, $password)) { $ftp.quit(); die " failed to login as user 'ftp', password $password - ", $ftp.message(), "[", $ftp.code(), "]\n"; } #------------------------------------------------------------------- # Change to the right directory, and set binary mode #------------------------------------------------------------------- _debug(" changing to \"$UPLOAD_DIR\" directory...\n"); if (!$ftp.cwd($UPLOAD_DIR)) { $ftp.quit(); die "failed to change directory to $UPLOAD_DIR!\n"; } _debug(" setting binary mode.\n"); unless $ftp.binary() { $ftp.quit(); die " failed to change type to 'binary' - ", $ftp.message(), "[", $ftp.code(), "]\n"; } #------------------------------------------------------------------- # Put the file(s) #------------------------------------------------------------------- for @files -> $file { _verbose(" uploading file \"$file\"\n"); if $ftp.put($file) { push(@uploaded, $file); } else { warn "failed to upload $file - ", $ftp.message(), "\n"; if (@files > 0 and !$config.non_interactive) { my $continue; repeat { print "Do you want to continue? [y] "; $continue = =$*IN; $continue = 'y' if $continue ~~ m:P5/^$/; } while $continue !~~ m:P5/^[ynYN]/; exit(0) if $continue ~~ m:P5/^[nN]/; } } } #------------------------------------------------------------------- # Close the connection with the server. #------------------------------------------------------------------- _debug(" closing connection with FTP server\n"); $ftp.quit; return @uploaded; } #======================================================================= # # pause_add_files() # # make an HTTP request to the add_uri form # #======================================================================= sub pause_add_files (*@files) { my $file; my $basename; my $request; my $response; my $agent; my $argref; _verbose("registering upload with PAUSE web server\n"); #------------------------------------------------------------------- # Create the agent we'll use to make the web requests #------------------------------------------------------------------- _debug(" creating instance of LWP::UserAgent\n"); $agent = LWP::UserAgent.new() orelse die "Failed to create UserAgent: $!\n"; $agent.agent("$PROGRAM/$VERSION"); $agent.from($config.mailto); if (defined $config.http_proxy) { $agent.proxy(['http'], $config.http_proxy); } #------------------------------------------------------------------- # Post an upload message to the PAUSE web site for each file #------------------------------------------------------------------- for @files -> $file { $basename = basename($file); #--------------------------------------------------------------- # Create the request to add the file #--------------------------------------------------------------- $argref = { 'HIDDENNAME' , "$config.user()", 'pause99_add_uri_upload' , "$basename", 'SUBMIT_pause99_add_uri_upload' , " Upload the checked file " }; if ($config.directory) { $argref.{'pause99_add_uri_subdirtext'} = $config.directory; } $request = POST($PAUSE_ADD_URI, $argref); $request.authorization_basic("$config.user()", "$config.password()"); _debug("----- REQUEST BEGIN -----\n", $request.as_string(), "----- REQUEST END -------\n"); #--------------------------------------------------------------- # Make the request to the PAUSE web server #--------------------------------------------------------------- _verbose(" POSTing upload for $file\n"); $response = $agent.request($request); #--------------------------------------------------------------- # So, how'd we do? #--------------------------------------------------------------- if (not defined $response) { die "Request completely failed - we got undef back: $!\n"; } if ($response.is_error) { if ($response.code == 404) { die "PAUSE's CGI for handling messages seems to have moved!\n", "(HTTP response code of 404 from the PAUSE web server)\n", "It used to be:\n\n\t", $PAUSE_ADD_URI, "\n\n", "Please inform the maintainer of this script\n"; } else { die "request failed\n Error code: ", $response.code, "\n Message: ", $response.message, "\n"; } } else { _debug("Looks OK!\n", "----- RESPONSE BEGIN -----\n", $response.as_string(), "----- RESPONSE END -------\n"); _verbose(" PAUSE add message sent ok [", $response.code, "]\n"); } } } #======================================================================= # # _verbose() # # displays the message strings passed if in verbose mode. # #======================================================================= sub _verbose { return unless $config.verbose; print join('', @_); } #======================================================================= # # _debug() # # displays the message strings passed if in debug mode. # #======================================================================= sub _debug { return unless $config.debug; print join('', @_); } __END__ #-----------------------------------------------------------------------