Created
April 14, 2011 20:40
-
-
Save gadhra/920483 to your computer and use it in GitHub Desktop.
This file, written in PHP 4, parsed qmail messages piped to it via a procmail rule (if I remember correctly). The script will parse anything sent to it via stdin.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @note Qmail popper::PHP4::qmail-popper-php | |
* @author Stefan Antonowicz | |
* | |
* This file parses out the mails sent to qmail via stdin. | |
* | |
* @author Stefan Antonowicz | |
*/ | |
error_reporting(E_ERROR | E_WARNING | E_PARSE); | |
/* Set constants and variables */ | |
$mime_types = array( 'image/jpeg'=>'.jpg', 'image/jpg'=>'.jpg', 'image/gif'=>'.gif', 'image/png'=>'.png' ); | |
$x_scale = 189; | |
define( 'ATTACH_DEST', '/home/foo/bar' ); | |
define( 'ATTACH_TMP', '/tmp' ); | |
/* | |
* A file name can be passed in instead i.e. `which php` qmail_popper.php -f foo.txt | |
*/ | |
if( $argv[1] == '-f' ) { | |
$fp = fopen( $argv[2], 'r' ); | |
} else { | |
$fp = fopen( "php://stdin", "r" ); | |
} | |
if(! $fp ) exit( 0 ); | |
$mail = ''; | |
while(! feof( $fp ) ) { | |
$line = fread( $fp, 1024 ); | |
$mail .= $line; | |
} | |
fclose( $fp ); | |
/* | |
* Time to start parsing out the headers, body, and attachments. Some of this | |
* borrowed from the PEAR mimeDecode class. | |
*/ | |
$mail = preg_replace( "/\r?\n/", "\r\n", $mail ); | |
$mail = preg_replace( "/\r\n(\t| )+/", ' ', $mail ); | |
$mail_array = explode( "\r\n", trim( $mail ) ); | |
foreach( $mail_array as $elem ) { | |
$elem = trim( $elem ); | |
$name = substr( $elem, 0, $pos = strpos( $elem, ':' ) ); | |
$value = substr( $elem, $pos + 1 ); | |
/* These are because PHP4 doesn't have stripos */ | |
$lower_name = strtolower( $name ); | |
$lower_elem = strtolower( $elem ); | |
$lower_value = strtolower( $value ); | |
/* Catch FROM and TO addresses in <foo@example.org> format */ | |
if( preg_match( "/<(.*)>/sU", $value, $match ) ) $value = $match[1]; | |
$value = trim( $value ); | |
if( $name ) { | |
if( strpos( $lower_name, 'content-type' ) !== FALSE ) { | |
/* get attachment type and set it as key. Also see if header is in the "forbidden" list */ | |
preg_match( '/(.*)($|;)/sU', $value, $key ); | |
preg_match( '/;.*=(.*)$/sU', $value, $mime_name ); | |
/* some systems put quotes around the mime name, others don't */ | |
if( $mime_name[1] ) $mime_name = str_replace( '"', '', $mime_name[1] ); | |
if( in_array( $mime_name, $bad_attach ) ) continue; | |
$headers[$name][] = $value; | |
$curname = trim( $key[1] ); | |
} else { | |
$headers[$name] = $value; | |
} | |
} elseif( $elem && strpos( $lower_elem, '_part_' ) === FALSE && strpos( $lower_elem, 'dngr' ) == FALSE ) { | |
$body[$curname][] = $elem; | |
} | |
} | |
$msg_array = $body['text/plain'] ? $body['text/plain'] : strip_tags( $body['text/html'] ); | |
/* | |
* NOTE: I submitted the message to the database and got a unique id for it, identified | |
* as $msgid. I also tried to determine the user information and parse any | |
* messages the user sent via SMS, which aren't important for this demonstration | |
*/ | |
if(! $msgid ) exit( 0 ); | |
$image_file = "img_" . time( ) . "_" . $msgid; | |
/* | |
* IMAGE HANDLING | |
*/ | |
foreach( $mime_types as $type=>$ext ) { | |
if( array_key_exists( $type, $body ) ) { | |
$image_file .= $ext; | |
$attach = implode( "\n", $body[$type] ); | |
$check_type = $type; | |
} | |
} | |
if( ! $attach ) exit( 0 ); | |
$payload = ATTACH_TMP. $image_file; | |
$h = fopen( $payload, 'w' ); | |
fwrite( $h, base64_decode( $attach ) ); | |
fclose( $h ); | |
if( class_exists( 'finfo' ) ) { | |
$finfo = new finfo( FILEINFO_MIME, MIME_DB ); // return mime type ala mimetype extension | |
$mtype = $finfo->file( $payload ); | |
} else { | |
$mtype = trim( exec( 'file -bi ' . escapeshellarg( $payload ) ) ); | |
} | |
if( $mtype != $check_type ) { | |
unlink( $payload ); | |
exit( 0 ); | |
} | |
/* | |
* Here I would pull the name of the last image submitted by the user, which would be $last_image | |
*/ | |
$last_image = $game->lastImage( ); | |
if(! $last_image || md5( file_get_contents( $payload ) ) != md5( file_get_contents( $last_image ) ) ) { | |
unlink( $payload ); | |
exit( 0 ); | |
} | |
/* | |
* Looking good - make directories and move the file over. This requires a user id generated earlier | |
*/ | |
$dest_dir = ATTACH_DEST . $user->id; | |
$thumb_dir = ATTACH_DEST . $user->id . '/thumbs'; | |
$destination = $dest_dir . '/' . $image_file; | |
if(! is_dir( $dest_dir ) ) | |
@mkdir( $dest_dir, 0777 ); | |
if(! is_dir( $thumb_dir ) ) | |
@mkdir( $thumb_dir, 0777 ); | |
rename( $payload, $destination ); | |
exit( 0 ); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment