File transfer protocol (FTP) is among the oldest Internet protocols.[41] It dates from the Internet’s predecessor ARPANET, which was originally funded by the Eisenhower administration.[42] Research centers started using FTP to exchange large files in the early 1970s, and FTP became the de facto transport protocol for email, a status it maintained until the early 1990s. Today, system administrators commonly use FTP to give web developers access to files on remote webservers. Though it’s an older protocol, FTP still allows computers with dissimilar technologies to share files, independent of file structure and operating system.
To better understand how an FTP-capable webbot may be useful, consider this scenario. A national retailer needs to move large sales reports from each of its stores to a centralized corporate webserver. This particular retail chain was built through acquisition, so it is built from proprietary computer systems using multiple protocols. The one thing all of these systems have in common is access to an FTP server. The goal for this project is to use the commonality of FTP to span the differences between systems to download store sales reports and move them to the corporate server.
The script for this example project is available for study at this book’s website. Just remember that the script satisfies a ficticious scenario and will not run unless you change the configuration. In this chapter, I have split it up and annotated the sections for clarity. Example 13-1 shows the initialization for the FTP servers.
Example 13-1. Initializing the FTP bot
<? // Define the source FTP server, file location, and authentication values define("REMOTE_FTP_SERVER", "remote_FTP_address"); // Domain name or IP address define("REMOTE_USERNAME", "yourUserName"); define("REMOTE_PASSWORD", "yourPassword"); define("REMOTE_DIRCTORY", "daily_sales"); define("REMOTE_FILE", "sales.txt"); // Define the corporate FTP server, file location, and authentication values define("CORP_FTP_SERVER", "corp_FTP_address"); define("CORP_USERNAME", "yourUserName"); define("CORP_PASSWORD", "yourPassword"); define("CORP_DIRCTORY", "sales_reports"); define("CORP_FILE", "store_03_".date("Y-M-d"));
This program also configures a routine to send a short email notification when commands fail. (Email functions for webbots, and LIB_mail
, are described in Chapter 14 and Chapter 15.) Automated email error notification allows the script to run autonomously without requiring that someone verify the operation manually.[43] Example 13-2 shows the email configuration script.
Example 13-2. Email configuration
include("LIB_MAIL.php"); $mail_addr['to'] = "admin@somedomain.com"; $mail_addr['from'] = "admin@somedomain.com"; function report_error_and_quit($error_message, $server_connection) { global $mail_addr; // Send error message echo "$error_message, $server_connection"; formatted_mail($error_message, $error_message, $mail_addr, "text/plain"); // Attempt to log off the server gracefully if possible ftp_close($server_connection); // It is not traditional to end a function this way, but since there is // nothing to return or do, it is best to exit exit(); }
The next step is to make a connection to the remote FTP server. After making the connection, the script authenticates itself with a username and password, as shown in Example 13-3.
Example 13-3. Connecting and authenticating with the remote server
// Negotiate a socket connection to the remote FTP server $remote_connection_id = ftp_connect(REMOTE_FTP_SERVER); // Log in (authenticate) the source server if(!ftp_login($remote_connection_id, REMOTE_USERNAME, REMOTE_PASSWORD)) report_error_and_quit("Remote ftp_login failed", $remote_connection_id);
Once authenticated by the server, the script moves to the target file’s directory and downloads the file to the local filesystem. After downloading the file, the script closes the connection to the remote server, as shown in Example 13-4.
Example 13-4. Downloading the file and closing the connection
// Move the directory of the source file if(!ftp_chdir($remote_connection_id, REMOTE_DIRCTORY)) report_error_and_quit("Remote ftp_chdir failed", $remote_connection_id); // Download the file if(!ftp_get($remote_connection_id, "temp_file", REMOTE_FILE, FTP_ASCII)) report_error_and_quit("Remote ftp_get failed", $remote_connection_id); // Close connections to the remote FTP server ftp_close($remote_connection_id);
The final task, shown in Example 13-5, uploads the file to the corporate server using techniques similar to the ones used to download the file.
Example 13-5. Logging in and uploading the previously downloaded file to the corporate server
// Negotiate a socket connection to the corporate FTP server $corp_connection_id = ftp_connect(CORP_FTP_SERVER); // Log in to the corporate server if(!ftp_login($corp_connection_id, CORP_USERNAME, CORP_PASSWORD)) report_error_and_quit("Corporate ftp_login failed", $corp_connection_id); // Move the destination directory if(!ftp_chdir($corp_connection_id, CORP_DIRECTORY)) report_error_and_quit("Corporate ftp_chdir failed", $corp_connection_id); // Upload the file if(!ftp_put($corp_connection_id, CORP_FILE, "temp_file", FTP_ASCII)) report_error_and_quit("Corporate ftp_put failed", $corp_connection_id); // Close connections to the corporate FTP server ftp_close($corp_connection_id); // Send notification that the webbot ran successfully formatted_mail("ftpbot ran successfully at ".time("M d,Y h:s"), "", $mail_addr, $content_type); ?>
[41] The original document defining FTP can be viewed at http://www.w3.org/Protocols/rfc959.
[42] Katie Hafner and Matthew Lyon, Where Wizards Stay Up Late: The Origins of the Internet (New York: Simon & Schuster, 1996), 14.
[43] See Chapter 22 for information on how to make webbots run periodically.