I found a few issues in the code. Most important, my image metadata was full of cruft. The site has been on two previous servers and goes back about six years. Happily, when I got the plugin running, it put 21,000 files on S3 in one go! WP_DEBUG in wp-config helps detect problems.
The #1 problem for me was an error doing fopen() on media files. The function getMediaFiles (ver. 1.12, cdn-sync-tool/lib/Cst/Sync.php, line 111) uses data from the table ‘wp_postmeta’ to get the paths of the media files. For some legacy/crufty reason, mine were absolute paths instead of relative. This breaks the plugin, which prepends the absolute path of the uploads directory. In fact, my data was not even accurate, since it had the wrong absolute paths from old servers. I cleaned it all up in MySQL (not an easy task, one field is serialized), but the plugin should be checking for this and maybe working around it. Typical bad data has the absolute path both in ‘_wp_attached_file’ and in the first serialized ‘file’ value in ‘_wp_attachment_metadata’. A correct, newly uploaded image in WP 3.3.1 has relative paths in both places.
#2 problem is a PHP gotcha introduced for security. Here is the warning, compliments of WP_DEBUG:
Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in […]/wp-content/plugins/cdn-sync-tool/lib/awssdk/lib/requestcore/requestcore.class.php on line 525
It was not safe_mode, it was the newer PHP feature “open_basedir”, which only can be overridden at the server level. If you have cPanel WHM (not plain cPanel), look for “PHP open_basedir Tweak” in the left hand menu. As for the plugin, I don’t know how important is CURLOPT_FOLLOWLOCATION (follow redirects), but it will not happen after the warning.
#3 problem is also due to open_basedir, but the warning probably has no effect. In cdn-sync-tool/lib/Cst/Sync.php there is an array_merge of two glob()s. Due to a bug in PHP, empty results of glob when open_basedir is on have the wrong type, false instead of empty array. See https://bugs.php.net/bug.php?id=47358
Complaints and workarounds for open_basedir can be found in the comments to the PHP documentation:
https://php.net/manual/en/function.curl-setopt.php
https://php.net/manual/es/function.glob.php