Old Code

Usage

ftp.pl [-netrc] [-u <i>user</i>] [-p <i>passwd</i>] -m server -s source_dir -t target_dir [-log_dir <i>/path/to/logs/file</i>] file1 file2 ...

# Copyright 2000 Williams Interactive, Inc.
# Programmer: Khurt Williams, 2000.10.18
# command switches are
# -netrc : uses .netrc file to find user/passwd for the destination server 
# -u <i>user</i> : specify the user id
# -p <i>passwd</i> :specify the passwd for user id
# -m server : server ip or name
# -s source_dir : source dir
# -t target_dir : target dir
# -log_dir <i>/path/to/logs/file</i> : location of log file

Code

#!/usr/local/bin/perl -w
# Copyright 2000 Williams Interactive, Inc.
# Programmer: Khurt Williams, 2000.10.18
# command switches are
# [-netrc] : uses .netrc file to find user/passwd for the destination server 
# [-u user] : specify the user id
# [-p passwd] :specify the passwd for user id
# -m server : server ip or name
# -s source_dir : source dir
# -t target_dir : target dir
# [-log_dir /path/to/log] : location of log file

use strict;
use Getopt::Long;
use Net::FTP;
use Net::Netrc;
use Log::ErrLogger;

my ($log_file,@file_list,$file,$return_code);
my ($netrc,$server,$source,$target,$user,$passwd,$log_dir,$ftp);
my ($machine,$login,$password);
my $options = { netrc => \$netrc, m => \$server, s => \$source, t => \$target, u => \$user, p => \$passwd, log_dir => \$log_dir };

GetOptions($options, "netrc","m=s","s=s","t=s","u:s","p:s","log_dir:s");

@file_list = @ARGV;

#make sure we have some filename
usage() if( !defined(@file_list) );

#use netrc
if( $netrc ) {
#exit if not server specified
 usage () if( !defined($server) );
#make sure we use the correct userid
 if( !defined($user) ) {
  $machine = Net::Netrc->lookup($server);
 }
 else {
  $machine = Net::Netrc->lookup($server,$user);
 }
#get login id and password for that server
 $login = $machine->login();
 $password = $machine->password();

 $user = $login;
 $passwd = $password;
}

#check that command line switches are set
usage() if( !defined($user) || !defined($passwd) || !defined($server));
usage() if( !defined($source) || !defined($target));

#append to log file if it already exist
$log_dir = "/tmp" if( !defined($log_dir) );
#log all event to file including die and warn
$log_file = new Log::ErrLogger::File( FILE => ">$log_dir/SendToML.log",SENSITVITY => Log::ErrLogger::ALL );

#connect to server
$ftp = new Net::FTP($server);
Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,__FILE__." ftp started.\n");
Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"ftp $server\n");
#exit and log message on failure
die($ftp->message()) if( !($ftp->login($user,$passwd)) );

#set mode to binary
Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"bin\n");
#exit and log message on failure
die($ftp->message()) if( !($ftp->binary()) );

#change local directory
chdir($source);
Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"lcd $source\n");

#change remote directory
Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"cd $target\n");
#exit and log message on failure
die($ftp->message()) if( !($ftp->cwd($target)) );

foreach $file (@file_list) {
#send files to server
 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"put $file $file\n");
 retry_put($file) if( !($ftp->put($file,$file)) );
}

#close connection
$return_code = $ftp->quit();
Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"quit\n");
Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,__FILE__." ftp ended.\n");

#end logging
$log_file->close();

exit(0);

sub usage {
 die "$0 [-netrc] [-u user] [-p passwd] -m [server]  -s [source_dir] -t [target_dir] [-log_dir [/path/to/logs/file]] file1 file2 ...\n";
}

#resend file if first attempt fails
#remove file if second attemp also fails.
sub retry_put {
 my ($file) = @_;

 warn($ftp->message());
 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"Will attempt to resend file %s.\n",$file);

 warn($ftp->message()) if( !($ftp->quit()) );
 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"quit\n");

 $ftp = new Net::FTP($server);
 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"ftp $server\n");
 die($ftp->message()) if( !($ftp->login($user,$passwd)) );

 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"cd $target\n");
 die($ftp->message()) if( !($ftp->cwd($target)) );

 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"put $file $file\n");
 remove_file($file) if( !($ftp->put($file,$file)) );
}

sub remove_file {
 my ($file) = @_;

 warn($ftp->message());
 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"Resend of $file failed.\n");
 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"Will attempt to remove half baked file $file.\n");

 warn($ftp->message()) if( !($ftp->quit()) );
 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"quit\n");

 $ftp = new Net::FTP($server);
 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"ftp $server\n");
 die($ftp->message()) if( !($ftp->login($user,$passwd)) );

 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"cd $target\n");
 die($ftp->message()) if( !($ftp->cwd($target)) );

 Log::ErrLogger::log_error(Log::ErrLogger::INFORMATIONAL,"delete $file\n");
 warn($ftp->message()) if( !($ftp->delete($file)) );
}
This is an excerpt from a much longer article, by writer and programmer Paul Ford, called What is Code. This part caught my attention.

It sometimes appears that everyone in coding has a beef. You can feel it coming off the Web pages. There are a lot of defensive postscripts added in response to outrage. “People have reacted strongly to this post,” they’ll read. “I did not mean to imply that Java sucks.”

Languages have agendas. People glom onto them. Blunt talk is seen as a good quality in a developer, a sign of an “engineering mindset”—spit out every opinion as quickly as possible, the sooner to reach a technical consensus. Expect to be told you’re wrong; expect to tell other people they’re wrong. (Masculine anger, bluntly expressed, is part of the industry.)

Coding is a culture of blurters. This can yield fast decisions, but it penalizes people who need to quietly compose their thoughts, rewarding fast-twitch thinkers who harrumph efficiently. Programmer job interviews, which often include abstract and meaningless questions that must be answered immediately on a whiteboard, typify this culture. Regular meetings can become sniping matches about things that don’t matter. The shorthand term for that is “bikeshedding.” (Who cares what color the bike shed is painted? Well?…)

Code culture is very, very broad, but the geographic and cultural core is the Silicon Valley engine of progress. The Valley mythologizes young geniuses with vast sums. To its credit, this culture works; to its shame, it doesn’t work for everyone.

At any moment some new thing could catch fire and disrupt the tribal ebb and flow. Instagram was written in Python and sold for $700 million?, so Python had a moment of glory. The next mind-blowing app could show up, written in some new language—and start everyone taking that more seriously. Within 18 months your skills could be, if not quite valueless, suspect.Paul Ford