Monday, October 16, 2006

FTP Upload Files Through Windows DOS Prompt

FTP Upload Files Through Windows DOS Prompt

Listing a huge list of directories and files from a server in a FTP client can be time consuming. This solution involves uploading files directly through the Windows FTP program.

To upload files to the server without a FTP client, create the following two files in the d:\ftp directory:

upload-ftp.bat (copy and paste the contents below)

cd ftp
ftp -s:files.txt
(Note: d: is the drive where these two files are located)

files.txt (copy and paste the contents below)
cd /var/www/remotedir

Double click to run the file upload-ftp.bat. The zip files to be uploaded need to be in the same directory (d:\ftp\ in this case) as the two files above.

Note: Ensure that the remote directory exists before uploading the files.

CRON line 1: Unexpected EOF while looking for matching ``'

CRON line 1: Unexpected EOF while looking for matching ``'

When running a CRON job that uses the command:
NOW=`date +%B_%d_%a_%Y`

the script will abort execution and display the following error:

/bin/sh: -c: line 1: unexpected EOF while looking for matching ``'
/bin/sh: -c: line 2: syntax error: unexpected end of file
To prevent this issue from occurring, dump the contents of the script into a .sh file and run the .sh from CRON.

Sometimes, CRON is set to use sh as opposed to the bash shell that the script needs.

The CRON shell can be modified in the /etc/crontab config file. Requires r00t privileges. Ensure that the CRON daemon is restarted after the modifications.

/sbin/service crond restart

Friday, October 13, 2006

Frequently Used .htaccess Directives in Apache

Frequently Used .htaccess Directives in Apache

# Force www
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.domain\.com$ [NC]
RewriteRule (.*)$1 [R=301,L]
RewriteRule ^(.*)$$0 [R=301,L]

# Add mod-rewrite rules (if needed)
# This checks if a file or directory exists before calling the var
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# This sends the var to the PHP file
RewriteRule ^([A-Za-z0-9_-]+)$0 [PT]

# Disable and turn off PHP register globals
php_flag register_globals OFF

# Enable PHP errors
php_flag display_errors ON

# Disable directory listing
IndexIgnore *

# Override common PHP settings
php_value post_max_size 16M
php_value upload_max_filesize 20M
php_value memory_limit 25M
php_value max_execution_time 900
php_value session.gc_maxlifetime 7200

# Hide the directory indexes
Options All -Indexes

# Show the directory indexes
Options All +Indexes

# Disable access and prevent viewing of htaccess

opentag Files .htaccess closetag
order allow,deny
deny from all
opentag /Files closetag

CHMOD .htaccess to 644 or RW-R--R--

# Disallow or prevent hotlinking of images, photos or any other file type
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?*$ [NC]
RewriteRule \.(gif|jpg)$ - [F]

# Redirect an old path to a new one
# Redirect an old file to a new file
Redirect /old-dir/foo.html

# Redirect an old directory to a new directory
Redirect /old-dir/

# Set the default index file
DirectoryIndex index.html

# Set multiple files as the default if the first doesn't exist
DirectoryIndex index1.html index2.php index3.shtml foo.htm

# Block or ban offline browsers or leechers
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^wget [OR]
RewriteCond %{HTTP_USER_AGENT} ^flashget [OR]
RewriteCond %{HTTP_USER_AGENT} ^getright
RewriteRule ^.* - [F,L]

# Ban traffic from a single or multiple domains
RewriteEngine on
# Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} foo\.com [NC]
RewriteRule .* - [F]


RewriteEngine on
# Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} foo1\.com [NC,OR]
RewriteCond %{HTTP_REFERER} foo2\.com
RewriteRule .* - [F]

Monday, October 09, 2006

preg_replace(): Error - Delimiter must not be alphanumeric or backslash

preg_replace(): Error - Delimiter must not be alphanumeric or backslash

preg_replace() will output a delimiter error if the "$pattern" does not have a / delimiter or if quotes are used when calling the preg_replace() function itself.

The Error:

$patterns[0] = '/PHP/4.4.4/';
$replacements[0] = "FooBar!";


The above will result in the following error:
"preg_replace(): Parameter mismatch, pattern is a string while replacement in an array"

Corrected Version:

// Delimiter is /
// Note: the forward slash after PHP is to be escaped with a backslash
// The i after the / is for case-insensitive matches. This means, you can match lower case words with upper case words and vice-versa

$patterns[0] = '/PHP\/4.4.4/i';
$replacements[0] = "FooBar!";

// Double quotes are to be removed

Sunday, October 08, 2006

CRON Fields

CRON Fields

# (Use to post in the top of your crontab)
# ------------- minute (0 - 59)
# | ----------- hour (0 - 23)
# | | --------- day of month (1 - 31)
# | | | ------- month (1 - 12)
# | | | | ----- day of week (0 - 6) (Sunday=0)
# | | | | |
# * * * * * command to be executed

* The comma (',') operator specifies a list of values, for example: "1,3,4,7,8"
* The dash ('-') operator specifies a range of values, for example: "1-6", which is equivalent to "1,2,3,4,5,6"
* The asterisk ('*') operator specifies all possible values for a field. For example, an asterisk in the hour time field would be equivalent to 'every hour'..


Delete All Email Using MUTT, Through SSH

Delete All Email Using MUTT, Through SSH

Since I login through SSH frequently, I use the MUTT email client to check email generated through automated scripts, logs etc. There were 40,000 emails that needed to be deleted quickly. I've been unable to find a "select all" option.

The solution involves, pressing the SHIFT and t key simultaneously. This will bring up the "tag messages matching feature". Enter the match that is common with all the emails. Eg: / and hit enter. (this will flag all the matching email with a *)

shift + t
Tag messages matching: /



The $ key will sync mutt - deleted emails will be purged, mailbox updated etc.

Disable CRON Output From Flooding Email

Disable CRON Output From Flooding Email

When a script is executed through CRON, the output can quickly flood an inbox. To disable output from specific scripts, append the following at the end of the script:

# Disable output completely

*/2 * * * * /usr/local/bin/php /test/foobar.php > /dev/null 2>&1

This script runs every two minutes.
Standard output (1) is redirected to /dev/null
Standard error (2) is directed to the same as standard output (1)

# Redirect script output to a log file
*/2 * * * * /usr/local/bin/php /test/foobar.php > /localpath/log.txt

# Redirect script output to a log file, append log
*/2 * * * * /usr/local/bin/php /test/foobar.php >> /localpath/log.txt

# Redirect script output and CLI error output to the same log file
*/2 * * * * /usr/local/bin/php /test/foobar.php > /localpath/log.txt 2>&1

/localpath/log.txt - This is standard output (1)
The 2 in the 2>&1 will direct standard error (2) to standard output. In this case, log.txt

# Redirect script output and CLI error output to a different log file
*/2 * * * * /usr/local/bin/php /test/foobar.php > /localpath/log.txt 2>/localpath/cli-errors.txt

# Redirect script output and CLI error output to a different log file, append log
*/2 * * * * /usr/local/bin/php /test/foobar.php >> /localpath/log.txt 2>>/localpath/cli-errors.txt

To test:
Execute this command
ls . IS >> errors.txt 2>>errors.txt

The second alternative is to modify the MAILTO= option and set it to "". This will however, disable all output from being sent to the email address specified in the MAILTO feature.

Another option would be to redirect the output to a text file and call the text file through the browser for analysis.

The php -q flag suppresses HTTP header output.

Saturday, October 07, 2006

Find and Replace the Exact Match in a String

To find and replace the exact match in a string, use the function ereg_replace. ereg will find the exact match and not a pattern.

// Strip the extra --
$string= ereg_replace("--","-",$string);
// Replace \n with a br tag
$string = str_replace("\n","

// Find and replace multiple needles in a haystack
$patterns[0] = '/>/';
$patterns[1] = '/1/';
$patterns[2] = "/2/";
$patterns[3] = '/3/';
$patterns[4] = '/4/';

// Escape non alpha characters
$patterns[5] = '/\"/';
$patterns[6] = '/\+/';
$patterns[7] = '/\'/';
$patterns[8] = '/\./';
$patterns[9] = '/Some Text/';

$replacements = '-';

$data = preg_replace($patterns, $replacements, $data);

PHP DOCUMENT_ROOT Include does not work with CRON

When including libraries or external files in PHP, the variable $_SERVER['DOCUMENT_ROOT'] will not call the external files if the script is run through CRON.

This is because, usually a PHP script would be executed through a /usr/local/bin/php -q directive. Since Apache does not play a role here, the DOCUMENT_ROOT variable will not work.

To ensure that the DOCUMENT_ROOT works, call the script through curl, wget or lynx. As a security measure, apps like wget are disabled on most servers. The alternative option is to get rid of the DOCUMENT_ROOT variable all together.

When including files in PHP scripts, it is best to create an includes.php in the base dir of the application. All scripts in the sub-directories can call the include file through a define path. The includes file can in turn define paths to other dependencies.


The -q flag suppresses HTTP header output. As long as your script itself does not send anything to stdout, -q will prevent cron from sending you an email every time the script runs. For example, print and echo send to stdout. Avoid using these functions if you want to prevent cron from sending you email.

The ../dirname directory include path does not work with cron too. The path needs to be included in full


Further Reference: